mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-06-07 05:38:13 +02:00
Compare commits
52 Commits
0d9f4b4fbd
...
c3e527549e
Author | SHA1 | Date | |
---|---|---|---|
|
c3e527549e | ||
|
ac8d1ed6a0 | ||
|
508a86b8ed | ||
|
f581d57c01 | ||
|
bed67ef1fb | ||
|
04237b7727 | ||
|
dc1ffdafcd | ||
|
eaf7c03f61 | ||
|
7892afa304 | ||
|
4c93647aaf | ||
|
881e8e36e8 | ||
|
0ff8774fce | ||
|
7a50df61b8 | ||
|
8860b4b678 | ||
|
b8852379f9 | ||
|
07a11addb9 | ||
|
4dde33c342 | ||
|
294adf6da5 | ||
|
5c7ea9131e | ||
|
27fa1a94fe | ||
|
80857758b4 | ||
|
153199b3b4 | ||
|
c7a29e4499 | ||
|
7b05853b7d | ||
|
d543dcdd80 | ||
|
58c4242ba5 | ||
|
1d53259988 | ||
|
f596c3b83c | ||
|
2ed0be0bcd | ||
|
a94e1eb573 | ||
|
6fd9414d37 | ||
|
05ffd79815 | ||
|
82dfbce231 | ||
|
3d35e322e9 | ||
|
f2002fc9a9 | ||
|
9caf07657d | ||
|
1c7c7ff4d6 | ||
|
a8dbb30139 | ||
|
59e9d01605 | ||
|
e99a7654af | ||
|
30de0cda70 | ||
|
ccbfeb11d0 | ||
|
e6e87f9ff7 | ||
|
83fd09939f | ||
|
2d32822ff8 | ||
|
772ec05049 | ||
|
18e08d13da | ||
|
1c2c1f710e | ||
|
013ffe5559 | ||
|
bcd35b02da | ||
|
b7d2808392 | ||
|
9bef90a151 |
44
CHANGELOG.md
44
CHANGELOG.md
|
@ -2,21 +2,61 @@
|
|||
|
||||
#### Next release (WIP)
|
||||
|
||||
* Experimental support for Redmi Watch 4
|
||||
* Initial support for Huawei Watch Fit 2
|
||||
* Introduce new Dashboard view
|
||||
* AsteroidOS: Added icons to the notifications
|
||||
* Bangle.js: Add screenshot support
|
||||
* Bangle.js: Add setting to disable notifications
|
||||
* Bangle.js: Allow wake phone when opening notification response from watch
|
||||
* Bangle.js: Fix activity intensity normalization
|
||||
* Bangle.js: Fix message reply
|
||||
* Fossil/Skagen Hybrids: Update device settings to new structure
|
||||
* Galaxy Buds Live: Update device settings to new structure
|
||||
* HPlus: Migrate global preferences to device-specific
|
||||
* Huawei: Add cycling workout type
|
||||
* Huawei: Add enable HeartRate and SpO2 force option
|
||||
* Huawei: Add huawei account support (pair without resetting watch)
|
||||
* Huawei: Add support for workout calories and cycling power
|
||||
* Huawei: Ask pincode only on first connection
|
||||
* Huawei: Enable sleep detection
|
||||
* Huawei: File upload and watchface management
|
||||
* Huawei: Fix force DND support
|
||||
* Huawei: Fix long notification
|
||||
* Huawei: Fix TimeZone offset calculation
|
||||
* Huawei: Improve connection and reconnection
|
||||
* Huawei: Improve notification icons
|
||||
* Huawei: Improve workout parsing
|
||||
* Huawei: Rework settings menu with sub-screens
|
||||
* Huawei: Support sending GPS to band
|
||||
* Huawei Watch GT4: Add HR and SpO support
|
||||
* Huawei Watch Ultimate: Add HR and SpO support
|
||||
* Intent API: Added debug end call
|
||||
* Mi Band 6: Add menu items for NFC shortcuts
|
||||
* Nothing CMF Watch Pro: Add weather support
|
||||
* Nothing Earbuds: Add adjustable delay for auto-pick-up of calls
|
||||
* Nothing Earbuds: Add option to auto-reply to incoming phone calls
|
||||
* Nothing Earbuds: Add option to read aloud incoming notifications
|
||||
* Xiaomi Smart Band 8 Active: Fix discovery
|
||||
* Xiaomi: Fix some crashes
|
||||
* Xiaomi: Improve reconnection
|
||||
* Xiaomi: Improve weather support, add multiple locations
|
||||
* Set navbar color to match theme
|
||||
* Xiaomi: Sync calendar event reminders
|
||||
* Zepp OS: Add support for Sleep as Android
|
||||
* Zepp OS: Sync calendar event reminders
|
||||
* Add Armenian and Serbian transliterators
|
||||
* Add GENERIC_PHONE and GENERIC_CALENDAR NotificationType handling
|
||||
* Add support for scannable-only devices
|
||||
* Fix crash when connecting on some phones
|
||||
* Fix crash when enabling bluetooth
|
||||
* Fix receiving shared gpx files
|
||||
* Format pace as mm:ss
|
||||
* Set navbar color to match theme
|
||||
* Simplify pairing of bonded and companion devices
|
||||
* Prevent text cutoff on all checkbox preferences
|
||||
* Recognize "Delta Chat" as generic chat
|
||||
* Remove deprecated general auto-reconnect preference
|
||||
* Refactor location service
|
||||
* Fix text cutoff on all checkbox preferences
|
||||
|
||||
#### 0.80.0
|
||||
* Initial support for Amazfit Bip 3
|
||||
|
|
|
@ -45,7 +45,7 @@ public class GBDaoGenerator {
|
|||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final Schema schema = new Schema(71, MAIN_PACKAGE + ".entities");
|
||||
final Schema schema = new Schema(73, MAIN_PACKAGE + ".entities");
|
||||
|
||||
Entity userAttributes = addUserAttributes(schema);
|
||||
Entity user = addUserInfo(schema, userAttributes);
|
||||
|
@ -1167,6 +1167,12 @@ public class GBDaoGenerator {
|
|||
|
||||
workoutDataSample.addByteArrayProperty("dataErrorHex");
|
||||
|
||||
workoutDataSample.addShortProperty("calories").notNull();
|
||||
workoutDataSample.addShortProperty("cyclingPower").notNull();
|
||||
|
||||
workoutDataSample.addShortProperty("frequency").notNull();
|
||||
workoutDataSample.addIntProperty("altitude");
|
||||
|
||||
return workoutDataSample;
|
||||
}
|
||||
|
||||
|
|
|
@ -178,10 +178,6 @@
|
|||
android:name=".devices.pebble.PebbleSettingsActivity"
|
||||
android:label="@string/pref_title_pebble_settings"
|
||||
android:parentActivityName=".activities.SettingsActivity" />
|
||||
<activity
|
||||
android:name=".devices.hplus.HPlusSettingsActivity"
|
||||
android:label="@string/preferences_hplus_settings"
|
||||
android:parentActivityName=".activities.SettingsActivity" />
|
||||
<activity
|
||||
android:name=".devices.zetime.ZeTimePreferenceActivity"
|
||||
android:label="@string/zetime_title_settings"
|
||||
|
|
|
@ -124,7 +124,7 @@ public class GBApplication extends Application {
|
|||
private static SharedPreferences sharedPrefs;
|
||||
private static final String PREFS_VERSION = "shared_preferences_version";
|
||||
//if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version
|
||||
private static final int CURRENT_PREFS_VERSION = 28;
|
||||
private static final int CURRENT_PREFS_VERSION = 29;
|
||||
|
||||
private static final LimitedQueue<Integer, String> mIDSenderLookup = new LimitedQueue<>(16);
|
||||
private static Prefs prefs;
|
||||
|
@ -1446,6 +1446,28 @@ public class GBApplication extends Application {
|
|||
}
|
||||
}
|
||||
|
||||
if (oldVersion < 29) {
|
||||
// Migrate HPlus preferences to device-specific
|
||||
try (DBHandler db = acquireDB()) {
|
||||
final DaoSession daoSession = db.getDaoSession();
|
||||
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
|
||||
|
||||
for (Device dbDevice : activeDevices) {
|
||||
final DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
if (deviceType == DeviceType.HPLUS) {
|
||||
final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
|
||||
|
||||
deviceSharedPrefsEdit.putString("hplus_screentime", sharedPrefs.getString("hplus_screentime", "5"));
|
||||
deviceSharedPrefsEdit.putBoolean("hplus_alldayhr", sharedPrefs.getBoolean("hplus_alldayhr", true));
|
||||
deviceSharedPrefsEdit.apply();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "error acquiring DB lock");
|
||||
}
|
||||
}
|
||||
|
||||
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
|
||||
editor.apply();
|
||||
}
|
||||
|
@ -1457,6 +1479,10 @@ public class GBApplication extends Application {
|
|||
return context.getSharedPreferences("devicesettings_" + deviceIdentifier, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public static Prefs getDevicePrefs(final String deviceIdentifier) {
|
||||
return new Prefs(getDeviceSpecificSharedPrefs(deviceIdentifier));
|
||||
}
|
||||
|
||||
public static void deleteDeviceSpecificSharedPrefs(String deviceIdentifier) {
|
||||
if (deviceIdentifier == null || deviceIdentifier.isEmpty()) {
|
||||
return;
|
||||
|
|
|
@ -71,6 +71,7 @@ import java.util.Comparator;
|
|||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
|
@ -518,6 +519,14 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
|||
|
||||
if (unit.equals("seconds") && !show_raw_data) { //rather then plain seconds, show formatted duration
|
||||
value_field.setText(DateTimeUtils.formatDurationHoursMinutes((long) value, TimeUnit.SECONDS));
|
||||
} else if (unit.equals("minutes_km") || unit.equals("minutes_mi")) {
|
||||
// Format pace
|
||||
value_field.setText(String.format(
|
||||
Locale.getDefault(),
|
||||
"%d:%02d %s",
|
||||
(int) Math.floor(value), (int) Math.round(60 * (value - (int) Math.floor(value))),
|
||||
getStringResourceByName(unit)
|
||||
));
|
||||
} else {
|
||||
value_field.setText(String.format("%s %s", df.format(value), getStringResourceByName(unit)));
|
||||
}
|
||||
|
|
|
@ -1184,7 +1184,10 @@ public class DebugActivity extends AbstractGBActivity {
|
|||
for (DeviceType deviceType : DeviceType.values()) {
|
||||
DeviceCoordinator coordinator = deviceType.getDeviceCoordinator();
|
||||
int icon = coordinator.getDefaultIconResource();
|
||||
String name = app.getString(coordinator.getDeviceNameResource()) + " (" + coordinator.getManufacturer() + ")";
|
||||
String name = app.getString(coordinator.getDeviceNameResource());
|
||||
if (!name.startsWith(coordinator.getManufacturer())) {
|
||||
name += " (" + coordinator.getManufacturer() + ")";
|
||||
}
|
||||
long deviceId = deviceType.ordinal();
|
||||
newMap.put(name, new Pair(deviceId, icon));
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ import java.util.Objects;
|
|||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.discovery.DiscoveryActivityV2;
|
||||
import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAdapterv2;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBAccess;
|
||||
|
@ -233,7 +234,8 @@ public class DevicesFragment extends Fragment {
|
|||
protected void doInBackground(DBHandler db) {
|
||||
for (GBDevice gbDevice : deviceList) {
|
||||
final DeviceCoordinator coordinator = gbDevice.getDeviceCoordinator();
|
||||
if (coordinator.supportsActivityTracking()) {
|
||||
boolean showActivityCard = GBApplication.getDevicePrefs(gbDevice.getAddress()).getBoolean(DeviceSettingsPreferenceConst.PREFS_ACTIVITY_IN_DEVICE_CARD, true);
|
||||
if (coordinator.supportsActivityTracking() && showActivityCard) {
|
||||
long[] stepsAndSleepData = getSteps(gbDevice, db);
|
||||
deviceActivityHashMap.put(gbDevice.getAddress(), stepsAndSleepData);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,6 @@ import nodomain.freeyourgadget.gadgetbridge.R;
|
|||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsPreferencesActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.discovery.DiscoveryPairingPreferenceActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.PeriodicExporter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusSettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleSettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.ConfigActivity;
|
||||
|
@ -156,15 +155,6 @@ public class SettingsActivity extends AbstractSettingsActivityV2 {
|
|||
});
|
||||
}
|
||||
|
||||
pref = findPreference("pref_key_hplus");
|
||||
if (pref != null) {
|
||||
pref.setOnPreferenceClickListener(preference -> {
|
||||
Intent enableIntent = new Intent(requireContext(), HPlusSettingsActivity.class);
|
||||
startActivity(enableIntent);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
pref = findPreference("pref_key_zetime");
|
||||
if (pref != null) {
|
||||
pref.setOnPreferenceClickListener(preference -> {
|
||||
|
|
|
@ -395,7 +395,7 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||
if (firstTimestamp == 0) firstTimestamp = sample.getTimestamp();
|
||||
if (lastTimestamp == 0) lastTimestamp = sample.getTimestamp();
|
||||
if ((sample.getHeartRate() < 10 || sample.getTimestamp() > lastTimestamp + dashboardData.hrIntervalSecs) && firstTimestamp != lastTimestamp) {
|
||||
LOG.info("Registered worn session from " + firstTimestamp + " to " + lastTimestamp);
|
||||
LOG.debug("Registered worn session from {} to {}", firstTimestamp, lastTimestamp);
|
||||
addActivity(firstTimestamp, lastTimestamp, ActivityKind.TYPE_NOT_MEASURED);
|
||||
if (sample.getHeartRate() < 10) {
|
||||
firstTimestamp = 0;
|
||||
|
@ -409,7 +409,7 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||
lastTimestamp = sample.getTimestamp();
|
||||
}
|
||||
if (firstTimestamp != lastTimestamp) {
|
||||
LOG.info("Registered worn session from " + firstTimestamp + " to " + lastTimestamp);
|
||||
LOG.debug("Registered worn session from {} to {}", firstTimestamp, lastTimestamp);
|
||||
addActivity(firstTimestamp, lastTimestamp, ActivityKind.TYPE_NOT_MEASURED);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,6 +343,25 @@ public class DeviceSettingsPreferenceConst {
|
|||
public static final String PREF_SONY_PROTOCOL_VERSION = "pref_protocol_version";
|
||||
public static final String PREF_SONY_ACTUAL_PROTOCOL_VERSION = "pref_actual_protocol_version";
|
||||
public static final String PREF_SONY_AMBIENT_SOUND_CONTROL = "pref_sony_ambient_sound_control";
|
||||
public static final String PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL = "pref_soundcore_ambient_sound_control";
|
||||
public static final String PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING = "pref_adaptive_noise_cancelling";
|
||||
public static final String PREF_SOUNDCORE_WIND_NOISE_REDUCTION= "pref_soundcore_wind_noise_reduction";
|
||||
public static final String PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE = "pref_soundcore_transparency_vocal_mode";
|
||||
public static final String PREF_SOUNDCORE_WEARING_DETECTION = "pref_soundcore_wearing_detection";
|
||||
public static final String PREF_SOUNDCORE_WEARING_TONE = "pref_soundcore_wearing_tone";
|
||||
public static final String PREF_SOUNDCORE_TOUCH_TONE = "pref_soundcore_touch_tone";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_SINGLE_TAP_DISABLED = "pref_soundcore_control_single_tap_disabled";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_DISABLED = "pref_soundcore_control_double_tap_disabled";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_DISABLED = "pref_soundcore_control_triple_tap_disabled";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_LONG_PRESS_DISABLED = "pref_soundcore_control_long_press_disabled";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_SINGLE_TAP_ACTION_LEFT = "pref_soundcore_control_single_tap_action_left";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_ACTION_LEFT = "pref_soundcore_control_double_tap_action_left";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_ACTION_LEFT = "pref_soundcore_control_triple_tap_action_left";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_LONG_PRESS_ACTION_LEFT = "pref_soundcore_control_long_press_action_left";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_SINGLE_TAP_ACTION_RIGHT = "pref_soundcore_control_single_tap_action_right";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_ACTION_RIGHT = "pref_soundcore_control_double_tap_action_right";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_ACTION_RIGHT = "pref_soundcore_control_triple_tap_action_right";
|
||||
public static final String PREF_SOUNDCORE_CONTROL_LONG_PRESS_ACTION_RIGHT = "pref_soundcore_control_long_press_action_right";
|
||||
public static final String PREF_SONY_AMBIENT_SOUND_CONTROL_BUTTON_MODE = "pref_sony_ambient_sound_control_button_mode";
|
||||
public static final String PREF_SONY_FOCUS_VOICE = "pref_sony_focus_voice";
|
||||
public static final String PREF_SONY_AMBIENT_SOUND_LEVEL = "pref_sony_ambient_sound_level";
|
||||
|
|
|
@ -563,6 +563,27 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i
|
|||
addPreferenceHandlerFor(PREF_SONY_CONNECT_TWO_DEVICES);
|
||||
addPreferenceHandlerFor(PREF_SONY_ADAPTIVE_VOLUME_CONTROL);
|
||||
addPreferenceHandlerFor(PREF_SONY_WIDE_AREA_TAP);
|
||||
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_WIND_NOISE_REDUCTION);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_TOUCH_TONE);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_WEARING_TONE);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_WEARING_DETECTION);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_SINGLE_TAP_DISABLED);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_DISABLED);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_DISABLED);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_LONG_PRESS_DISABLED);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_SINGLE_TAP_ACTION_LEFT);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_SINGLE_TAP_ACTION_RIGHT);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_ACTION_LEFT);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_ACTION_RIGHT);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_ACTION_LEFT);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_ACTION_RIGHT);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_LONG_PRESS_ACTION_LEFT);
|
||||
addPreferenceHandlerFor(PREF_SOUNDCORE_CONTROL_LONG_PRESS_ACTION_RIGHT);
|
||||
|
||||
addPreferenceHandlerFor(PREF_FEMOMETER_MEASUREMENT_MODE);
|
||||
|
||||
addPreferenceHandlerFor(PREF_QC35_NOISE_CANCELLING_LEVEL);
|
||||
|
@ -922,6 +943,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i
|
|||
setInputTypeFor(DeviceSettingsPreferenceConst.PREF_DEVICE_GPS_UPDATE_INTERVAL, InputType.TYPE_CLASS_NUMBER);
|
||||
setInputTypeFor(DeviceSettingsPreferenceConst.PREF_BANGLEJS_TEXT_BITMAP_SIZE, InputType.TYPE_CLASS_NUMBER);
|
||||
setInputTypeFor(DeviceSettingsPreferenceConst.PREF_AUTO_REPLY_INCOMING_CALL_DELAY, InputType.TYPE_CLASS_NUMBER);
|
||||
setInputTypeFor("hplus_screentime", InputType.TYPE_CLASS_NUMBER);
|
||||
|
||||
new PasswordCapabilityImpl().registerPreferences(getContext(), coordinator.getPasswordCapability(), this);
|
||||
new HeartRateCapability().registerPreferences(getContext(), coordinator.getHeartRateMeasurementIntervals(), this);
|
||||
|
|
|
@ -34,6 +34,7 @@ public enum DeviceSpecificSettingsScreen {
|
|||
DATE_TIME("pref_screen_date_time", R.xml.devicesettings_root_date_time),
|
||||
WORKOUT("pref_screen_workout", R.xml.devicesettings_root_workout),
|
||||
HEALTH("pref_screen_health", R.xml.devicesettings_root_health),
|
||||
TOUCH_OPTIONS("pref_screen_touch_options", R.xml.devicesettings_root_touch_options),
|
||||
;
|
||||
|
||||
private final String key;
|
||||
|
|
|
@ -1316,6 +1316,13 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
|
|||
}
|
||||
|
||||
private void setActivityCard(ViewHolder holder, final GBDevice device, long[] dailyTotals) {
|
||||
boolean showActivityCard = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()).getBoolean(DeviceSettingsPreferenceConst.PREFS_ACTIVITY_IN_DEVICE_CARD, true);
|
||||
holder.cardViewActivityCardLayout.setVisibility(showActivityCard ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (!showActivityCard) {
|
||||
return;
|
||||
}
|
||||
|
||||
int steps = (int) dailyTotals[0];
|
||||
int sleep = (int) dailyTotals[1];
|
||||
ActivityUser activityUser = new ActivityUser();
|
||||
|
@ -1336,8 +1343,6 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
|
|||
setUpChart(holder.SleepTimeChart);
|
||||
setChartsData(holder.SleepTimeChart, sleep, sleepGoalMinutes, context.getString(R.string.prefs_activity_in_device_card_sleep_title), String.format("%1s", getHM(sleep)), context);
|
||||
|
||||
boolean showActivityCard = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()).getBoolean(DeviceSettingsPreferenceConst.PREFS_ACTIVITY_IN_DEVICE_CARD, true);
|
||||
holder.cardViewActivityCardLayout.setVisibility(showActivityCard ? View.VISIBLE : View.GONE);
|
||||
|
||||
boolean showActivitySteps = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()).getBoolean(DeviceSettingsPreferenceConst.PREFS_ACTIVITY_IN_DEVICE_CARD_STEPS, true);
|
||||
boolean showActivitySleep = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()).getBoolean(DeviceSettingsPreferenceConst.PREFS_ACTIVITY_IN_DEVICE_CARD_SLEEP, true);
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* Copyright (C) 2024 Martin.JM
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.database.schema;
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutDataSampleDao;
|
||||
|
||||
public class GadgetbridgeUpdate_72 implements DBUpdateScript {
|
||||
@Override
|
||||
public void upgradeSchema(final SQLiteDatabase db) {
|
||||
if (!DBHelper.existsColumn(HuaweiWorkoutDataSampleDao.TABLENAME, HuaweiWorkoutDataSampleDao.Properties.Calories.columnName, db)) {
|
||||
final String statement = "ALTER TABLE " + HuaweiWorkoutDataSampleDao.TABLENAME + " ADD COLUMN \""
|
||||
+ HuaweiWorkoutDataSampleDao.Properties.Calories.columnName + "\" INTEGER NOT NULL DEFAULT -1";
|
||||
db.execSQL(statement);
|
||||
}
|
||||
if (!DBHelper.existsColumn(HuaweiWorkoutDataSampleDao.TABLENAME, HuaweiWorkoutDataSampleDao.Properties.CyclingPower.columnName, db)) {
|
||||
final String statement = "ALTER TABLE " + HuaweiWorkoutDataSampleDao.TABLENAME + " ADD COLUMN \""
|
||||
+ HuaweiWorkoutDataSampleDao.Properties.CyclingPower.columnName + "\" INTEGER NOT NULL DEFAULT -1";
|
||||
db.execSQL(statement);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downgradeSchema(final SQLiteDatabase db) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* Copyright (C) 2024 Martin.JM
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.database.schema;
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutDataSampleDao;
|
||||
|
||||
public class GadgetbridgeUpdate_73 implements DBUpdateScript {
|
||||
@Override
|
||||
public void upgradeSchema(final SQLiteDatabase db) {
|
||||
if (!DBHelper.existsColumn(HuaweiWorkoutDataSampleDao.TABLENAME, HuaweiWorkoutDataSampleDao.Properties.Frequency.columnName, db)) {
|
||||
final String statement = "ALTER TABLE " + HuaweiWorkoutDataSampleDao.TABLENAME + " ADD COLUMN \""
|
||||
+ HuaweiWorkoutDataSampleDao.Properties.Frequency.columnName + "\" INTEGER NOT NULL DEFAULT -1";
|
||||
db.execSQL(statement);
|
||||
}
|
||||
if (!DBHelper.existsColumn(HuaweiWorkoutDataSampleDao.TABLENAME, HuaweiWorkoutDataSampleDao.Properties.Altitude.columnName, db)) {
|
||||
final String statement = "ALTER TABLE " + HuaweiWorkoutDataSampleDao.TABLENAME + " ADD COLUMN \""
|
||||
+ HuaweiWorkoutDataSampleDao.Properties.Altitude.columnName + "\" INTEGER DEFAULT NULL";
|
||||
db.execSQL(statement);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downgradeSchema(final SQLiteDatabase db) {
|
||||
}
|
||||
}
|
|
@ -100,6 +100,25 @@ public abstract class AbstractTimeSampleProvider<T extends AbstractTimeSample> i
|
|||
return samples.get(0);
|
||||
}
|
||||
|
||||
public T getLastSampleBefore(final long timestampTo) {
|
||||
final Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
|
||||
if (dbDevice == null) {
|
||||
// no device, no sample
|
||||
return null;
|
||||
}
|
||||
|
||||
final Property deviceIdSampleProp = getDeviceIdentifierSampleProperty();
|
||||
final Property timestampSampleProp = getTimestampSampleProperty();
|
||||
final List<T> samples = getSampleDao().queryBuilder()
|
||||
.where(deviceIdSampleProp.eq(dbDevice.getId()),
|
||||
timestampSampleProp.le(timestampTo))
|
||||
.orderDesc(getTimestampSampleProperty())
|
||||
.limit(1)
|
||||
.list();
|
||||
|
||||
return !samples.isEmpty() ? samples.get(0) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public T getFirstSample() {
|
||||
|
|
|
@ -23,14 +23,13 @@ import java.util.regex.Pattern;
|
|||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
|
||||
public class GalaxyBuds2DeviceCoordinator extends GalaxyBudsGenericCoordinator {
|
||||
@Override
|
||||
protected Pattern getSupportedDeviceName() {
|
||||
return Pattern.compile("Galaxy Buds2 \\(.*");
|
||||
// Some devices are just called "Buds2", others "Galaxy Buds2 (..."
|
||||
return Pattern.compile("(Galaxy )?Buds2( \\(.*)?");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,11 +18,8 @@
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.le.ScanFilter;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelUuid;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -42,16 +39,13 @@ import nodomain.freeyourgadget.gadgetbridge.R;
|
|||
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
|
||||
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.entities.HPlusHealthActivitySampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.hplus.HPlusSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||
|
@ -81,36 +75,16 @@ public class HPlusCoordinator extends AbstractBLEDeviceCoordinator {
|
|||
return BONDING_STYLE_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCalendarEvents() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsRealtimeData() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsWeather() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFindDevice() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Activity> getPairingActivity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallHandler findInstallHandler(Uri uri, Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsActivityDataFetching() {
|
||||
return true;
|
||||
|
@ -126,11 +100,6 @@ public class HPlusCoordinator extends AbstractBLEDeviceCoordinator {
|
|||
return new HPlusHealthSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsScreenshots(final GBDevice device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlarmSlotCount(GBDevice device) {
|
||||
return 3; // FIXME - check the real value
|
||||
|
@ -146,16 +115,6 @@ public class HPlusCoordinator extends AbstractBLEDeviceCoordinator {
|
|||
return "Zeblaze";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAppsManagement(final GBDevice device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Activity> getAppsManagementActivity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
||||
Long deviceId = device.getId();
|
||||
|
@ -236,11 +195,11 @@ public class HPlusCoordinator extends AbstractBLEDeviceCoordinator {
|
|||
}
|
||||
|
||||
public static byte getScreenTime(String address) {
|
||||
return (byte) (prefs.getInt(HPlusConstants.PREF_HPLUS_SCREENTIME, 5) & 0xFF);
|
||||
return (byte) (GBApplication.getDevicePrefs(address).getInt(HPlusConstants.PREF_HPLUS_SCREENTIME, 5) & 0xFF);
|
||||
}
|
||||
|
||||
public static byte getAllDayHR(String address) {
|
||||
boolean value = (prefs.getBoolean(HPlusConstants.PREF_HPLUS_ALLDAYHR, true));
|
||||
boolean value = (GBApplication.getDevicePrefs(address).getBoolean(HPlusConstants.PREF_HPLUS_ALLDAYHR, true));
|
||||
|
||||
if (value) {
|
||||
return HPlusConstants.ARG_HEARTRATE_ALLDAY_ON;
|
||||
|
@ -310,6 +269,7 @@ public class HPlusCoordinator extends AbstractBLEDeviceCoordinator {
|
|||
return new int[]{
|
||||
//R.xml.devicesettings_wearlocation, // disabled, since it is never used in code
|
||||
R.xml.devicesettings_timeformat,
|
||||
R.xml.devicesettings_hplus,
|
||||
R.xml.devicesettings_transliteration
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/* Copyright (C) 2023-2024 José Rebelo
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivityV2;
|
||||
|
||||
public class HPlusSettingsActivity extends AbstractSettingsActivityV2 {
|
||||
@Override
|
||||
protected String fragmentTag() {
|
||||
return HPlusSettingsFragment.FRAGMENT_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PreferenceFragmentCompat newFragment() {
|
||||
return new HPlusSettingsFragment();
|
||||
}
|
||||
|
||||
public static class HPlusSettingsFragment extends AbstractPreferenceFragment {
|
||||
static final String FRAGMENT_TAG = "HPLUS_SETTINGS_FRAGMENT";
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
|
||||
setPreferencesFromResource(R.xml.hplus_preferences, rootKey);
|
||||
|
||||
setInputTypeFor("hplus_screentime", InputType.TYPE_CLASS_NUMBER);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -66,6 +66,7 @@ public final class HuaweiConstants {
|
|||
public static final String HU_WATCHGT3PRO_NAME = "huawei watch gt 3 pro-";
|
||||
public static final String HU_WATCHGT4_NAME = "huawei watch gt 4-";
|
||||
public static final String HU_WATCHFIT_NAME = "huawei watch fit-";
|
||||
public static final String HU_WATCHFIT2_NAME = "huawei watch fit 2-";
|
||||
public static final String HU_WATCHULTIMATE_NAME = "huawei watch ultimate-";
|
||||
|
||||
public static final String PREF_HUAWEI_ADDRESS = "huawei_address";
|
||||
|
|
|
@ -317,6 +317,10 @@ public class HuaweiCoordinator {
|
|||
public boolean supportsMotionGoal() {
|
||||
return supportsCommandForService(0x07, 0x01);
|
||||
}
|
||||
|
||||
public boolean supportsUserInfo() {
|
||||
return supportsCommandForService(0x07, 0x02);
|
||||
}
|
||||
|
||||
public boolean supportsInactivityWarnings() {
|
||||
return supportsCommandForService(0x07, 0x06);
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/* Copyright (C) 2024 Damien Gaignon
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweiwatchfit2;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiBRCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
|
||||
public class HuaweiWatchFit2Coordinator extends HuaweiBRCoordinator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HuaweiWatchFit2Coordinator.class);
|
||||
|
||||
public HuaweiWatchFit2Coordinator() {
|
||||
super();
|
||||
getHuaweiCoordinator().setTransactionCrypted(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceType getDeviceType() {
|
||||
return DeviceType.HUAWEIWATCHFIT2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern getSupportedDeviceName() {
|
||||
return Pattern.compile("(" + HuaweiConstants.HU_WATCHFIT2_NAME + ").*", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeviceNameResource() {
|
||||
return R.string.devicetype_huawei_watchfit2;
|
||||
}
|
||||
}
|
|
@ -22,11 +22,15 @@ import org.slf4j.LoggerFactory;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiBRCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiSpo2SampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Spo2Sample;
|
||||
|
||||
public class HuaweiWatchGT4Coordinator extends HuaweiBRCoordinator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HuaweiWatchGT4Coordinator.class);
|
||||
|
@ -46,6 +50,21 @@ public class HuaweiWatchGT4Coordinator extends HuaweiBRCoordinator {
|
|||
return Pattern.compile("(" + HuaweiConstants.HU_WATCHGT4_NAME + ").*", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsHeartRateMeasurement(GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSpo2() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends Spo2Sample> getSpo2SampleProvider(GBDevice device, DaoSession session) {
|
||||
return new HuaweiSpo2SampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeviceNameResource() {
|
||||
return R.string.devicetype_huawei_watchgt4;
|
||||
|
|
|
@ -22,10 +22,14 @@ import org.slf4j.LoggerFactory;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiBRCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiSpo2SampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Spo2Sample;
|
||||
|
||||
public class HuaweiWatchUltimateCoordinator extends HuaweiBRCoordinator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HuaweiWatchUltimateCoordinator.class);
|
||||
|
@ -45,6 +49,21 @@ public class HuaweiWatchUltimateCoordinator extends HuaweiBRCoordinator {
|
|||
return Pattern.compile("(" + HuaweiConstants.HU_WATCHULTIMATE_NAME + ").*", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsHeartRateMeasurement(GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSpo2() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends Spo2Sample> getSpo2SampleProvider(GBDevice device, DaoSession session) {
|
||||
return new HuaweiSpo2SampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeviceNameResource() {
|
||||
return R.string.devicetype_huawei_watchultimate;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2024 Damien Gaignon, Martin.JM
|
||||
/* Copyright (C) 2024 Damien Gaignon, Martin.JM, Vitalii Tomin
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
|
@ -71,6 +71,34 @@ public class FitnessData {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class UserInfo {
|
||||
public static final byte id = 0x02;
|
||||
public static class Request extends HuaweiPacket {
|
||||
public Request(ParamsProvider paramsProvider,
|
||||
int height,
|
||||
int weight,
|
||||
int age,
|
||||
int birthdayEncoded,
|
||||
byte gender) {
|
||||
super(paramsProvider);
|
||||
this.serviceId = FitnessData.id;
|
||||
this.commandId = id;
|
||||
|
||||
byte bmi1 = (byte)Math.round(0.42f * height);
|
||||
byte bmi2 = (byte)Math.round(0.83f * height);
|
||||
|
||||
this.tlv = new HuaweiTLV()
|
||||
.put(0x01, (byte)height)
|
||||
.put(0x02, (byte)weight)
|
||||
.put(0x03, (byte)age)
|
||||
.put(0x04, birthdayEncoded)
|
||||
.put(0x05, gender)
|
||||
.put(0x06, bmi1)
|
||||
.put(0x07, bmi2);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static class MessageCount {
|
||||
public static final byte sleepId = 0x0C;
|
||||
public static final byte stepId = 0x0A;
|
||||
|
|
|
@ -239,12 +239,17 @@ public class Workout {
|
|||
public byte swolf = -1;
|
||||
public short strokeRate = -1;
|
||||
|
||||
public short calories = -1;
|
||||
public short cyclingPower = -1;
|
||||
public short frequency = -1;
|
||||
public Integer altitude = null;
|
||||
|
||||
public int timestamp = -1; // Calculated timestamp for this data point
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Data{" +
|
||||
"unknownData=" + unknownData +
|
||||
"unknownData=" + Arrays.toString(unknownData) +
|
||||
", heartRate=" + heartRate +
|
||||
", speed=" + speed +
|
||||
", stepRate=" + stepRate +
|
||||
|
@ -259,13 +264,17 @@ public class Workout {
|
|||
", eversionAngle=" + eversionAngle +
|
||||
", swolf=" + swolf +
|
||||
", strokeRate=" + strokeRate +
|
||||
", calories=" + calories +
|
||||
", cyclingPower=" + cyclingPower +
|
||||
", frequency=" + frequency +
|
||||
", altitude=" + altitude +
|
||||
", timestamp=" + timestamp +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
// I'm not sure about the lengths, but we haven't gotten any complaints so they probably are fine
|
||||
private final byte[] bitmapLengths = {1, 2, 1, 2, 2, 4, -1, 2, 2, 1, 1, 1, 1, 1, 1, 1};
|
||||
private final byte[] bitmapLengths = {1, 2, 1, 2, 2, 4, -1, 2, 2, 2, 1, 1, 1, 1, 1, 1};
|
||||
private final byte[] innerBitmapLengths = {2, 2, 2, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1};
|
||||
|
||||
public short workoutNumber;
|
||||
|
@ -367,6 +376,9 @@ public class Workout {
|
|||
case 4:
|
||||
data.strokeRate = buf.getShort();
|
||||
break;
|
||||
case 5:
|
||||
data.altitude = buf.getInt();
|
||||
break;
|
||||
case 6:
|
||||
// Inner data, parsing into data
|
||||
// TODO: function for readability?
|
||||
|
@ -410,6 +422,15 @@ public class Workout {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
data.calories = buf.getShort();
|
||||
break;
|
||||
case 8:
|
||||
data.frequency = buf.getShort();
|
||||
break;
|
||||
case 9:
|
||||
data.cyclingPower = buf.getShort();
|
||||
break;
|
||||
default:
|
||||
data.unknownData = this.tlv.serialize();
|
||||
// Fix alignment
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package nodomain.freeyourgadget.gadgetbridge.devices.soundcore;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsScreen;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore.SoundcoreLiberty3ProDeviceSupport;
|
||||
|
||||
public class SoundcoreLiberty3ProCoordinator extends AbstractDeviceCoordinator {
|
||||
@Override
|
||||
public int getDeviceNameResource() {
|
||||
return R.string.devicetype_soundcore_liberty3_pro;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultIconResource() {
|
||||
return R.drawable.ic_device_galaxy_buds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisabledIconResource() {
|
||||
return R.drawable.ic_device_galaxy_buds_disabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManufacturer() {
|
||||
return "Anker";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern getSupportedDeviceName() {
|
||||
return Pattern.compile("Soundcore Liberty 3 Pro");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBondingStyle(){
|
||||
return BONDING_STYLE_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBatteryCount() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BatteryConfig[] getBatteryConfig() {
|
||||
BatteryConfig battery1 = new BatteryConfig(0, R.drawable.ic_buds_pro_case, R.string.battery_case);
|
||||
BatteryConfig battery2 = new BatteryConfig(1, R.drawable.ic_nothing_ear_l, R.string.left_earbud);
|
||||
BatteryConfig battery3 = new BatteryConfig(2, R.drawable.ic_nothing_ear_r, R.string.right_earbud);
|
||||
return new BatteryConfig[]{battery1, battery2, battery3};
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) {
|
||||
final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings();
|
||||
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.TOUCH_OPTIONS);
|
||||
deviceSpecificSettings.addSubScreen(DeviceSpecificSettingsScreen.TOUCH_OPTIONS, R.xml.devicesettings_sony_headphones_ambient_sound_control_button_modes);
|
||||
deviceSpecificSettings.addSubScreen(DeviceSpecificSettingsScreen.TOUCH_OPTIONS, R.xml.devicesettings_soundcore_touch_options);
|
||||
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_soundcore_headphones);
|
||||
return deviceSpecificSettings;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Class<? extends DeviceSupport> getDeviceSupportClass() {
|
||||
return SoundcoreLiberty3ProDeviceSupport.class;
|
||||
}
|
||||
}
|
|
@ -457,6 +457,7 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator {
|
|||
if (getCannedRepliesSlotCount(device) > 0) {
|
||||
notifications.add(R.xml.devicesettings_canned_dismisscall_16);
|
||||
}
|
||||
notifications.add(R.xml.devicesettings_transliteration);
|
||||
|
||||
//
|
||||
// Calendar
|
||||
|
|
|
@ -97,60 +97,80 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
|
|||
return samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.activity.impl.SleepDetailsParser}
|
||||
*/
|
||||
private static int getActivityKindForSample(final XiaomiSleepStageSample sample) {
|
||||
switch (sample.getStage()) {
|
||||
case 2:
|
||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
||||
case 3:
|
||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
||||
case 4:
|
||||
return ActivityKind.TYPE_REM_SLEEP;
|
||||
default: // default to awake
|
||||
return ActivityKind.TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overlay sleep states on activity samples, since they are stored on a separate table.
|
||||
*
|
||||
* @implNote This currently needs to look back a further 24h, so that we are sure that we
|
||||
* got the sleep start of a sleep session at the start of the samples, if any. This is especially
|
||||
* noticeable if the charts are configured in a noon-to-noon setting. FIXME: This is not ideal,
|
||||
* and we may need to rethink the way sleep samples are persisted in the database for Xiaomi devices.
|
||||
* @implNote In order to determine whether a sleep session was ongoing at the start of the
|
||||
* given range and what the detected sleep stage was at that time, the last sleep stage and
|
||||
* sleep time sample before the given range will be queried and included in the results if
|
||||
* found.
|
||||
*/
|
||||
public void overlaySleep(final List<XiaomiActivitySample> samples, final int timestamp_from, final int timestamp_to) {
|
||||
final RangeMap<Long, Integer> stagesMap = new RangeMap<>();
|
||||
|
||||
final XiaomiSleepStageSampleProvider sleepStagesSampleProvider = new XiaomiSleepStageSampleProvider(getDevice(), getSession());
|
||||
final List<XiaomiSleepStageSample> stageSamples = sleepStagesSampleProvider.getAllSamples(
|
||||
timestamp_from * 1000L - 86400000L,
|
||||
|
||||
// Retrieve the last stage before this time range, as the user could have been asleep during
|
||||
// the range transition
|
||||
final XiaomiSleepStageSample lastSleepStageBeforeRange = sleepStagesSampleProvider.getLastSampleBefore(timestamp_from * 1000L);
|
||||
|
||||
if (lastSleepStageBeforeRange != null) {
|
||||
LOG.debug("Last sleep stage before range: ts={}, stage={}", lastSleepStageBeforeRange.getTimestamp(), lastSleepStageBeforeRange.getStage());
|
||||
stagesMap.put(lastSleepStageBeforeRange.getTimestamp(), getActivityKindForSample(lastSleepStageBeforeRange));
|
||||
}
|
||||
|
||||
// Retrieve all sleep stage samples during the range
|
||||
final List<XiaomiSleepStageSample> sleepStagesInRange = sleepStagesSampleProvider.getAllSamples(
|
||||
timestamp_from * 1000L,
|
||||
timestamp_to * 1000L
|
||||
);
|
||||
if (!stageSamples.isEmpty()) {
|
||||
|
||||
if (!sleepStagesInRange.isEmpty()) {
|
||||
// We got actual sleep stages
|
||||
LOG.debug("Found {} sleep stage samples between {} and {}", stageSamples.size(), timestamp_from, timestamp_to);
|
||||
LOG.debug("Found {} sleep stage samples between {} and {}", sleepStagesInRange.size(), timestamp_from, timestamp_to);
|
||||
|
||||
for (final XiaomiSleepStageSample stageSample : stageSamples) {
|
||||
final int activityKind;
|
||||
|
||||
switch (stageSample.getStage()) {
|
||||
case 2: // deep
|
||||
activityKind = ActivityKind.TYPE_DEEP_SLEEP;
|
||||
break;
|
||||
case 3: // light
|
||||
activityKind = ActivityKind.TYPE_LIGHT_SLEEP;
|
||||
break;
|
||||
case 4: // rem
|
||||
activityKind = ActivityKind.TYPE_REM_SLEEP;
|
||||
break;
|
||||
case 0: // final awake
|
||||
case 1: // ?
|
||||
case 5: // awake during the night
|
||||
default:
|
||||
activityKind = ActivityKind.TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
stagesMap.put(stageSample.getTimestamp(), activityKind);
|
||||
for (final XiaomiSleepStageSample stageSample : sleepStagesInRange) {
|
||||
stagesMap.put(stageSample.getTimestamp(), getActivityKindForSample(stageSample));
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch bed and wakeup times as well.
|
||||
final XiaomiSleepTimeSampleProvider sleepTimeSampleProvider = new XiaomiSleepTimeSampleProvider(getDevice(), getSession());
|
||||
final List<XiaomiSleepTimeSample> sleepTimeSamples = sleepTimeSampleProvider.getAllSamples(
|
||||
timestamp_from * 1000L - 86400000L,
|
||||
|
||||
// Find last sleep sample before the requested range, as the recorded wake up time may be
|
||||
// in the current range
|
||||
final XiaomiSleepTimeSample lastSleepTimesBeforeRange = sleepTimeSampleProvider.getLastSampleBefore(timestamp_from * 1000L);
|
||||
|
||||
if (lastSleepTimesBeforeRange != null) {
|
||||
stagesMap.put(lastSleepTimesBeforeRange.getWakeupTime(), ActivityKind.TYPE_UNKNOWN);
|
||||
stagesMap.put(lastSleepTimesBeforeRange.getTimestamp(), ActivityKind.TYPE_LIGHT_SLEEP);
|
||||
}
|
||||
|
||||
// Find all wake up and sleep samples in the current time range
|
||||
final List<XiaomiSleepTimeSample> sleepTimesInRange = sleepTimeSampleProvider.getAllSamples(
|
||||
timestamp_from * 1000L,
|
||||
timestamp_to * 1000L
|
||||
);
|
||||
if (!sleepTimeSamples.isEmpty()) {
|
||||
LOG.debug("Found {} sleep samples between {} and {}", sleepTimeSamples.size(), timestamp_from, timestamp_to);
|
||||
for (final XiaomiSleepTimeSample stageSample : sleepTimeSamples) {
|
||||
if (stageSamples.isEmpty()) {
|
||||
|
||||
if (!sleepTimesInRange.isEmpty()) {
|
||||
LOG.debug("Found {} sleep samples between {} and {}", sleepTimesInRange.size(), timestamp_from, timestamp_to);
|
||||
for (final XiaomiSleepTimeSample stageSample : sleepTimesInRange) {
|
||||
if (sleepStagesInRange.isEmpty()) {
|
||||
// Only overlay them as light sleep if we don't have actual sleep stages
|
||||
stagesMap.put(stageSample.getTimestamp(), ActivityKind.TYPE_LIGHT_SLEEP);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ public class IntentApiReceiver extends BroadcastReceiver {
|
|||
public static final String COMMAND_TRIGGER_EXPORT = "nodomain.freeyourgadget.gadgetbridge.command.TRIGGER_EXPORT";
|
||||
public static final String COMMAND_DEBUG_SEND_NOTIFICATION = "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_SEND_NOTIFICATION";
|
||||
public static final String COMMAND_DEBUG_INCOMING_CALL = "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_INCOMING_CALL";
|
||||
public static final String COMMAND_DEBUG_END_CALL = "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_END_CALL";
|
||||
public static final String COMMAND_DEBUG_SET_DEVICE_ADDRESS = "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_SET_DEVICE_ADDRESS";
|
||||
public static final String COMMAND_DEBUG_TEST_NEW_FUNCTION = "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION";
|
||||
|
||||
|
@ -168,6 +169,18 @@ public class IntentApiReceiver extends BroadcastReceiver {
|
|||
}
|
||||
GBApplication.deviceService().onSetCallState(callSpec);
|
||||
break;
|
||||
|
||||
case COMMAND_DEBUG_END_CALL:
|
||||
if (!prefs.getBoolean("intent_api_allow_debug_commands", false)) {
|
||||
LOG.warn(msgDebugNotAllowed);
|
||||
return;
|
||||
}
|
||||
LOG.info("Triggering Debug End Call");
|
||||
CallSpec callSpecEnd = new CallSpec();
|
||||
callSpecEnd.command = CallSpec.CALL_END;
|
||||
GBApplication.deviceService().onSetCallState(callSpecEnd);
|
||||
break;
|
||||
|
||||
case COMMAND_DEBUG_SET_DEVICE_ADDRESS:
|
||||
if (!prefs.getBoolean("intent_api_allow_debug_commands", false)) {
|
||||
LOG.warn(msgDebugNotAllowed);
|
||||
|
@ -193,6 +206,7 @@ public class IntentApiReceiver extends BroadcastReceiver {
|
|||
intentFilter.addAction(COMMAND_TRIGGER_EXPORT);
|
||||
intentFilter.addAction(COMMAND_DEBUG_SEND_NOTIFICATION);
|
||||
intentFilter.addAction(COMMAND_DEBUG_INCOMING_CALL);
|
||||
intentFilter.addAction(COMMAND_DEBUG_END_CALL);
|
||||
intentFilter.addAction(COMMAND_DEBUG_SET_DEVICE_ADDRESS);
|
||||
intentFilter.addAction(COMMAND_DEBUG_TEST_NEW_FUNCTION);
|
||||
return intentFilter;
|
||||
|
|
|
@ -106,6 +106,10 @@ public class ActivitySummaryEntries {
|
|||
public static final String MAXIMUM_OXYGEN_UPTAKE = "maximumOxygenUptake";
|
||||
public static final String RECOVERY_TIME = "recoveryTime";
|
||||
|
||||
public static final String CYCLING_POWER_AVERAGE = "cyclingPowerAverage";
|
||||
public static final String CYCLING_POWER_MIN = "cyclingPowerMin";
|
||||
public static final String CYCLING_POWER_MAX = "cyclingPowerMax";
|
||||
|
||||
public static final String UNIT_BPM = "bpm";
|
||||
public static final String UNIT_CM = "cm";
|
||||
public static final String UNIT_UNIX_EPOCH_SECONDS = "unix_epoch_seconds";
|
||||
|
|
|
@ -119,6 +119,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweiband8.HuaweiBan
|
|||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweibandaw70.HuaweiBandAw70Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweitalkbandb6.HuaweiTalkBandB6Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweiwatchfit.HuaweiWatchFitCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweiwatchfit2.HuaweiWatchFit2Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweiwatchgt.HuaweiWatchGTCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweiwatchgt2.HuaweiWatchGT2Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.huaweiwatchgt2e.HuaweiWatchGT2eCoordinator;
|
||||
|
@ -167,6 +168,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators
|
|||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyWH1000XM5Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.wena3.SonyWena3Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12.SonySWR12DeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.soundcore.SoundcoreLiberty3ProCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.supercars.SuperCarsCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.test.TestDeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.tlw64.TLW64Coordinator;
|
||||
|
@ -347,6 +349,7 @@ public enum DeviceType {
|
|||
SONY_LINKBUDS_S(SonyLinkBudsSCoordinator.class),
|
||||
SONY_WH_1000XM5(SonyWH1000XM5Coordinator.class),
|
||||
SONY_WF_1000XM5(SonyWF1000XM5Coordinator.class),
|
||||
SOUNDCORE_LIBERTY3_PRO(SoundcoreLiberty3ProCoordinator.class),
|
||||
BOSE_QC35(QC35Coordinator.class),
|
||||
HONORBAND3(HonorBand3Coordinator.class),
|
||||
HONORBAND4(HonorBand4Coordinator.class),
|
||||
|
@ -366,6 +369,7 @@ public enum DeviceType {
|
|||
HUAWEIWATCHGT4(HuaweiWatchGT4Coordinator.class),
|
||||
HUAWEIBAND8(HuaweiBand8Coordinator.class),
|
||||
HUAWEIWATCHFIT(HuaweiWatchFitCoordinator.class),
|
||||
HUAWEIWATCHFIT2(HuaweiWatchFit2Coordinator.class),
|
||||
HUAWEIWATCHULTIMATE(HuaweiWatchUltimateCoordinator.class),
|
||||
VESC(VescCoordinator.class),
|
||||
BINARY_SENSOR(BinarySensorCoordinator.class),
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package nodomain.freeyourgadget.gadgetbridge.service.btle;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Service;
|
||||
|
@ -326,8 +327,8 @@ public class BLEScanService extends Service {
|
|||
unregisterReceiver(bluetoothStateChangedReceiver);
|
||||
}
|
||||
|
||||
private boolean hasBluetoothPermission(){
|
||||
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.R){
|
||||
private boolean hasBluetoothPermission() {
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
|
||||
// workaround. Cannot give bluetooth permission on Android O
|
||||
LOG.warn("Running on android 11, skipping bluetooth permission check");
|
||||
return ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
|
||||
|
@ -335,6 +336,7 @@ public class BLEScanService extends Service {
|
|||
return ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission") // linter does not recognize the usage of hasBluetoothPermission
|
||||
private void restartScan(boolean applyFilters) {
|
||||
if (!hasBluetoothPermission()) {
|
||||
// this should never happen
|
||||
|
@ -357,7 +359,9 @@ public class BLEScanService extends Service {
|
|||
return;
|
||||
}
|
||||
if (currentState.isDoingAnyScan()) {
|
||||
scanner.stopScan(scanCallback);
|
||||
if (hasBluetoothPermission()) {
|
||||
scanner.stopScan(scanCallback);
|
||||
}
|
||||
}
|
||||
ArrayList<ScanFilter> scanFilters = null;
|
||||
|
||||
|
@ -375,7 +379,7 @@ public class BLEScanService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
if (scanFilters.size() == 0) {
|
||||
if (scanFilters.isEmpty()) {
|
||||
// no need to start scanning
|
||||
LOG.debug("restartScan: stopping BLE scan, no devices");
|
||||
currentState = ScanningState.NOT_SCANNING;
|
||||
|
|
|
@ -88,6 +88,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetN
|
|||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetSmartAlarmList;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetWatchfaceParams;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendExtendedAccountRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFitnessUserInfoRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsAndTimeToDeviceRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsDataRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadInfo;
|
||||
|
@ -505,6 +506,7 @@ public class HuaweiSupportProvider {
|
|||
}
|
||||
onSetTime();
|
||||
getBatteryLevel();
|
||||
sendUserInfo();
|
||||
if (isBLE()) {
|
||||
assert leBuilder != null;
|
||||
leBuilder.add(new nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction(gbDevice, GBDevice.State.INITIALIZED, context));
|
||||
|
@ -963,6 +965,12 @@ public class HuaweiSupportProvider {
|
|||
case ActivityUser.PREF_USER_STEPS_GOAL:
|
||||
new SendFitnessGoalRequest(this).doPerform();
|
||||
break;
|
||||
case ActivityUser.PREF_USER_WEIGHT_KG:
|
||||
case ActivityUser.PREF_USER_HEIGHT_CM:
|
||||
case ActivityUser.PREF_USER_GENDER:
|
||||
case ActivityUser.PREF_USER_YEAR_OF_BIRTH:
|
||||
sendUserInfo();
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO: Use translatable string
|
||||
|
@ -1513,7 +1521,11 @@ public class HuaweiSupportProvider {
|
|||
data.eversionAngle,
|
||||
data.swolf,
|
||||
data.strokeRate,
|
||||
unknown
|
||||
unknown,
|
||||
data.calories,
|
||||
data.cyclingPower,
|
||||
data.frequency,
|
||||
data.altitude
|
||||
);
|
||||
dao.insertOrReplace(dataSample);
|
||||
}
|
||||
|
@ -1566,6 +1578,17 @@ public class HuaweiSupportProvider {
|
|||
}
|
||||
}
|
||||
|
||||
public void sendUserInfo() {
|
||||
try {
|
||||
SendFitnessUserInfoRequest sendFitnessUserInfoRequest = new SendFitnessUserInfoRequest(this);
|
||||
sendFitnessUserInfoRequest.doPerform();
|
||||
} catch (IOException e) {
|
||||
GB.toast(context, "Failed to set user info", Toast.LENGTH_SHORT, GB.ERROR, e);
|
||||
LOG.error("Failed to set user info", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setActivateOnLift() {
|
||||
try {
|
||||
SetActivateOnLiftRequest setActivateOnLiftReq = new SetActivateOnLiftRequest(this);
|
||||
|
|
|
@ -106,7 +106,11 @@ public class HuaweiWorkoutGbParser {
|
|||
responseData.eversionAngle,
|
||||
responseData.swolf,
|
||||
responseData.strokeRate,
|
||||
dataErrorHex
|
||||
dataErrorHex,
|
||||
responseData.calories,
|
||||
responseData.cyclingPower,
|
||||
responseData.frequency,
|
||||
responseData.altitude
|
||||
);
|
||||
|
||||
dbHandler.getDaoSession().getHuaweiWorkoutDataSampleDao().insertOrReplace(dataSample);
|
||||
|
@ -301,6 +305,18 @@ public class HuaweiWorkoutGbParser {
|
|||
int heartRateCount = 0;
|
||||
int maxHeartRate = 0;
|
||||
int minHeartRate = Integer.MAX_VALUE;
|
||||
int sumCalories = 0;
|
||||
int minCyclingPower = Integer.MAX_VALUE;
|
||||
int maxCyclingPower = 0;
|
||||
int cyclingPower = 0;
|
||||
int cyclingPowerCount = 0;
|
||||
int avgAltitude = 0;
|
||||
int altitudeCount = 0;
|
||||
int minAltitude = 0;
|
||||
int maxAltitude = 0;
|
||||
Integer previousAlt = null;
|
||||
int sumAltitudeUp = 0;
|
||||
int sumAltitudeDown = 0;
|
||||
for (HuaweiWorkoutDataSample dataSample : dataSamples) {
|
||||
if (dataSample.getSpeed() != -1) {
|
||||
speed += dataSample.getSpeed();
|
||||
|
@ -373,6 +389,33 @@ public class HuaweiWorkoutGbParser {
|
|||
if (hr < minHeartRate)
|
||||
minHeartRate = hr;
|
||||
}
|
||||
if (dataSample.getCalories() != -1)
|
||||
sumCalories += dataSample.getCalories();
|
||||
if (dataSample.getCyclingPower() != -1) {
|
||||
int cp = dataSample.getCyclingPower();
|
||||
cyclingPower += cp;
|
||||
cyclingPowerCount += 1;
|
||||
if (cp > maxCyclingPower)
|
||||
maxCyclingPower = cp;
|
||||
if (cp < minCyclingPower)
|
||||
minCyclingPower = cp;
|
||||
}
|
||||
if (dataSample.getAltitude() != null) {
|
||||
int alt = dataSample.getAltitude();
|
||||
avgAltitude += alt;
|
||||
altitudeCount += 1;
|
||||
if (alt > maxAltitude)
|
||||
maxAltitude = alt;
|
||||
if (alt < minAltitude)
|
||||
minAltitude = alt;
|
||||
if (previousAlt != null) {
|
||||
if (alt > previousAlt)
|
||||
sumAltitudeUp += alt - previousAlt;
|
||||
else if (alt < previousAlt)
|
||||
sumAltitudeDown += previousAlt - alt;
|
||||
}
|
||||
previousAlt = alt;
|
||||
}
|
||||
if (dataSample.getDataErrorHex() != null)
|
||||
unknownData = true;
|
||||
}
|
||||
|
@ -400,6 +443,10 @@ public class HuaweiWorkoutGbParser {
|
|||
strokeRate = strokeRate / strokeRateCount;
|
||||
if (heartRateCount > 0)
|
||||
heartRate = heartRate / heartRateCount;
|
||||
if (cyclingPowerCount > 0)
|
||||
cyclingPower = cyclingPower / cyclingPowerCount;
|
||||
if (altitudeCount > 0)
|
||||
avgAltitude = avgAltitude / altitudeCount;
|
||||
|
||||
if (speedCount > 0) {
|
||||
JSONObject speedJson = new JSONObject();
|
||||
|
@ -534,6 +581,57 @@ public class HuaweiWorkoutGbParser {
|
|||
minHeartRateJson.put("unit", ActivitySummaryEntries.UNIT_BPM);
|
||||
jsonObject.put(ActivitySummaryEntries.HR_MIN, minHeartRateJson);
|
||||
}
|
||||
|
||||
if (sumCalories > 0) {
|
||||
JSONObject caloriesSumJson = new JSONObject();
|
||||
caloriesSumJson.put("value", sumCalories);
|
||||
caloriesSumJson.put("unit", ActivitySummaryEntries.UNIT_KCAL);
|
||||
jsonObject.put(ActivitySummaryEntries.CALORIES_BURNT, caloriesSumJson);
|
||||
}
|
||||
|
||||
if (cyclingPowerCount > 0) {
|
||||
JSONObject cyclingPowerJson = new JSONObject();
|
||||
cyclingPowerJson.put("value", cyclingPower);
|
||||
cyclingPowerJson.put("unit", "");
|
||||
jsonObject.put(ActivitySummaryEntries.CYCLING_POWER_AVERAGE, cyclingPowerJson);
|
||||
|
||||
JSONObject minCyclingPowerJson = new JSONObject();
|
||||
minCyclingPowerJson.put("value", minCyclingPower);
|
||||
minCyclingPowerJson.put("unit", "");
|
||||
jsonObject.put(ActivitySummaryEntries.CYCLING_POWER_MIN, minCyclingPowerJson);
|
||||
|
||||
JSONObject maxCyclingPowerJson = new JSONObject();
|
||||
maxCyclingPowerJson.put("value", maxCyclingPower);
|
||||
maxCyclingPowerJson.put("unit", "");
|
||||
jsonObject.put(ActivitySummaryEntries.CYCLING_POWER_MAX, maxCyclingPowerJson);
|
||||
}
|
||||
|
||||
if (altitudeCount > 0) {
|
||||
JSONObject avgAltitudeJson = new JSONObject();
|
||||
avgAltitudeJson.put("value", avgAltitude);
|
||||
avgAltitudeJson.put("unit", "");
|
||||
jsonObject.put(ActivitySummaryEntries.ALTITUDE_AVG, avgAltitudeJson);
|
||||
|
||||
JSONObject minAltitudeJson = new JSONObject();
|
||||
minAltitudeJson.put("value", minAltitude);
|
||||
minAltitudeJson.put("unit", "");
|
||||
jsonObject.put(ActivitySummaryEntries.ALTITUDE_MIN, minAltitudeJson);
|
||||
|
||||
JSONObject maxAltitudeJson = new JSONObject();
|
||||
maxAltitudeJson.put("value", maxAltitude);
|
||||
maxAltitudeJson.put("unit", "");
|
||||
jsonObject.put(ActivitySummaryEntries.ALTITUDE_MAX, maxAltitudeJson);
|
||||
|
||||
JSONObject sumUpAltitudeJson = new JSONObject();
|
||||
sumUpAltitudeJson.put("value", sumAltitudeUp);
|
||||
sumUpAltitudeJson.put("unit", "");
|
||||
jsonObject.put(ActivitySummaryEntries.ELEVATION_GAIN, sumUpAltitudeJson);
|
||||
|
||||
JSONObject sumDownAltitudeJson = new JSONObject();
|
||||
sumDownAltitudeJson.put("value", sumAltitudeDown);
|
||||
sumDownAltitudeJson.put("unit", "");
|
||||
jsonObject.put(ActivitySummaryEntries.ELEVATION_LOSS, sumDownAltitudeJson);
|
||||
}
|
||||
}
|
||||
|
||||
try (CloseableListIterator<HuaweiWorkoutPaceSample> it = qbPace.build().listIterator()) {
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* Copyright (C) 2024 Vitalii Tomin
|
||||
|
||||
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 <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FitnessData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FitnessData.UserInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
|
||||
|
||||
public class SendFitnessUserInfoRequest extends Request {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SendFitnessUserInfoRequest.class);
|
||||
|
||||
public SendFitnessUserInfoRequest(HuaweiSupportProvider support) {
|
||||
super(support);
|
||||
this.serviceId = FitnessData.id;
|
||||
this.commandId = UserInfo.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||
try {
|
||||
// Hardcoded values till interface for goal
|
||||
ActivityUser activityUser = new ActivityUser();
|
||||
byte gender = 3;
|
||||
if (activityUser.getGender() == ActivityUser.GENDER_FEMALE) {
|
||||
gender = 2;
|
||||
} else if (activityUser.getGender() == ActivityUser.GENDER_MALE) {
|
||||
gender = 1;
|
||||
}
|
||||
|
||||
Date birthday = activityUser.getUserBirthday();
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(birthday);
|
||||
int birthdayEncoded = cal.get(Calendar.YEAR) << 16;
|
||||
birthdayEncoded += (cal.get(Calendar.MONTH)+1) << 8;
|
||||
birthdayEncoded += cal.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
return new UserInfo.Request(paramsProvider,
|
||||
activityUser.getHeightCm(),
|
||||
activityUser.getWeightKg(),
|
||||
activityUser.getAge(),
|
||||
birthdayEncoded,
|
||||
gender
|
||||
).serialize();
|
||||
} catch (HuaweiPacket.CryptoException e) {
|
||||
throw new RequestCreationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processResponse() {
|
||||
LOG.debug("handle Send Fitness UserInfo Request");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
|
||||
public class SoundcoreLiberty3ProDeviceSupport extends AbstractSerialDeviceSupport {
|
||||
|
||||
@Override
|
||||
public boolean connect() {
|
||||
getDeviceIOThread().start();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAutoConnect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GBDeviceProtocol createDeviceProtocol() {
|
||||
return new SoundcoreLibertyProtocol(getDevice());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized GBDeviceIoThread createDeviceIOThread() {
|
||||
return new SoundcoreLibertyIOThread(getDevice(), getContext(),
|
||||
(SoundcoreLibertyProtocol) getDeviceProtocol(),
|
||||
SoundcoreLiberty3ProDeviceSupport.this, getBluetoothAdapter());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.hexdump;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
import android.os.ParcelUuid;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread;
|
||||
|
||||
public class SoundcoreLibertyIOThread extends BtClassicIoThread {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SoundcoreLibertyIOThread.class);
|
||||
private final SoundcoreLibertyProtocol mSoundcoreProtocol;
|
||||
|
||||
public SoundcoreLibertyIOThread(GBDevice gbDevice, Context context, SoundcoreLibertyProtocol deviceProtocol, SoundcoreLiberty3ProDeviceSupport deviceSupport, BluetoothAdapter btAdapter) {
|
||||
super(gbDevice, context, deviceProtocol, deviceSupport, btAdapter);
|
||||
mSoundcoreProtocol = deviceProtocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
write(mSoundcoreProtocol.encodeDeviceInfoRequest());
|
||||
setUpdateState(GBDevice.State.INITIALIZED);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected UUID getUuidToConnect(@NonNull ParcelUuid[] uuids) {
|
||||
return mSoundcoreProtocol.UUID_DEVICE_CTRL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] parseIncoming(InputStream inStream) throws IOException {
|
||||
byte[] buffer = new byte[1048576]; //HUGE read
|
||||
int bytes = inStream.read(buffer);
|
||||
LOG.debug("read " + bytes + " bytes. " + hexdump(buffer, 0, bytes));
|
||||
return Arrays.copyOf(buffer, bytes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,377 @@
|
|||
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.hexdump;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.prefs.AmbientSoundControlButtonMode;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
public class SoundcoreLibertyProtocol extends GBDeviceProtocol {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SoundcoreLibertyProtocol.class);
|
||||
|
||||
private static final int battery_case = 0;
|
||||
private static final int battery_earphone_left = 1;
|
||||
private static final int battery_earphone_right = 2;
|
||||
|
||||
final UUID UUID_DEVICE_CTRL = UUID.fromString("0cf12d31-fac3-4553-bd80-d6832e7b3952");
|
||||
|
||||
protected SoundcoreLibertyProtocol(GBDevice device) {
|
||||
super(device);
|
||||
}
|
||||
|
||||
private GBDeviceEventBatteryInfo buildBatteryInfo(int batteryIndex, int level) {
|
||||
GBDeviceEventBatteryInfo info = new GBDeviceEventBatteryInfo();
|
||||
info.batteryIndex = batteryIndex;
|
||||
info.level = level;
|
||||
return info;
|
||||
}
|
||||
|
||||
private GBDeviceEventVersionInfo buildVersionInfo(String firmware1, String firmware2, String serialNumber) {
|
||||
GBDeviceEventVersionInfo info = new GBDeviceEventVersionInfo();
|
||||
info.hwVersion = serialNumber;
|
||||
info.fwVersion = firmware1;
|
||||
info.fwVersion2 = firmware2;
|
||||
return info;
|
||||
}
|
||||
|
||||
private String readString(byte[] data, int position, int size) {
|
||||
if (position + size > data.length) throw new IllegalStateException();
|
||||
return new String(data, position, size, StandardCharsets.UTF_8);
|
||||
}
|
||||
@Override
|
||||
public GBDeviceEvent[] decodeResponse(byte[] responseData) {
|
||||
// Byte 0-4: Header
|
||||
// Byte 5-6: Command (Audio-Mode)
|
||||
// Byte 7: Size of data
|
||||
// Byte 8-(x-1): Data
|
||||
// Byte x: Checksum
|
||||
if (responseData.length == 0) return null;
|
||||
|
||||
List<GBDeviceEvent> devEvts = new ArrayList<>();
|
||||
|
||||
byte[] command = Arrays.copyOfRange(responseData, 5, 7);
|
||||
byte[] data = Arrays.copyOfRange(responseData, 8, responseData.length-1);
|
||||
|
||||
if (Arrays.equals(command, new byte[]{0x01, 0x01})) {
|
||||
// a lot of other data is in here, anything interesting?
|
||||
String firmware1 = readString(data, 7, 5);
|
||||
String firmware2 = readString(data, 12, 5);
|
||||
String serialNumber = readString(data, 17, 16);
|
||||
devEvts.add(buildVersionInfo(firmware1, firmware2, serialNumber));
|
||||
} else if (Arrays.equals(command, new byte[]{0x01, (byte) 0x8d})) {
|
||||
LOG.debug("Unknown incoming message - command: " + hexdump(command) + ", dump: " + hexdump(responseData));
|
||||
} else if (Arrays.equals(command, new byte[]{0x05, (byte) 0x82})) {
|
||||
LOG.debug("Unknown incoming message - command: " + hexdump(command) + ", dump: " + hexdump(responseData));
|
||||
} else if (Arrays.equals(command, new byte[]{0x05, 0x01})) {
|
||||
LOG.debug("Unknown incoming message - command: " + hexdump(command) + ", dump: " + hexdump(responseData));
|
||||
} else if (Arrays.equals(command, new byte[]{0x06, 0x01})) { //Sound Mode Update
|
||||
decodeAudioMode(data);
|
||||
} else if (Arrays.equals(command, new byte[]{0x01, 0x03})) { // Battery Update
|
||||
int batteryLeft = data[1] * 20;
|
||||
int batteryRight = data[2] * 20;
|
||||
int batteryCase = data[3] * 20;
|
||||
|
||||
devEvts.add(buildBatteryInfo(battery_case, batteryCase));
|
||||
devEvts.add(buildBatteryInfo(battery_earphone_left, batteryLeft));
|
||||
devEvts.add(buildBatteryInfo(battery_earphone_right, batteryRight));
|
||||
} else {
|
||||
// see https://github.com/gmallios/SoundcoreManager/blob/master/soundcore-lib/src/models/packet_kind.rs
|
||||
// for a mapping for other soundcore devices (similar protocol?)
|
||||
LOG.debug("Unknown incoming message - command: " + hexdump(command) + ", dump: " + hexdump(responseData));
|
||||
}
|
||||
return devEvts.toArray(new GBDeviceEvent[devEvts.size()]);
|
||||
}
|
||||
|
||||
private void decodeAudioMode(byte[] payload) {
|
||||
SharedPreferences prefs = getDevicePrefs().getPreferences();
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
String soundmode = "off";
|
||||
int anc_strength = 0;
|
||||
|
||||
if (payload[1] == 0x00) {
|
||||
soundmode = "noise_cancelling";
|
||||
} else if (payload[1] == 0x01) {
|
||||
soundmode = "ambient_sound";
|
||||
} else if (payload[1] == 0x02) {
|
||||
soundmode = "off";
|
||||
}
|
||||
|
||||
if (payload[2] == 0x10) {
|
||||
anc_strength = 0;
|
||||
} else if (payload[2] == 0x20) {
|
||||
anc_strength = 1;
|
||||
} else if (payload[2] == 0x30) {
|
||||
anc_strength = 2;
|
||||
}
|
||||
|
||||
boolean vocal_mode = (payload[3] == 0x01);
|
||||
boolean adaptive_anc = (payload[4] == 0x01);
|
||||
boolean windnoiseReduction = (payload[5] == 0x01);
|
||||
|
||||
editor.putString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL, soundmode);
|
||||
editor.putInt(DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_LEVEL, anc_strength);
|
||||
editor.putBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE, vocal_mode);
|
||||
editor.putBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING, adaptive_anc);
|
||||
editor.putBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_WIND_NOISE_REDUCTION, windnoiseReduction);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encodeSendConfiguration(String config) {
|
||||
Prefs prefs = getDevicePrefs();
|
||||
String pref_string;
|
||||
|
||||
switch (config) {
|
||||
// Ambient Sound Modes
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL:
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_WIND_NOISE_REDUCTION:
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE:
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING:
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_LEVEL:
|
||||
return encodeAudioMode();
|
||||
|
||||
// Control
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_SINGLE_TAP_DISABLED:
|
||||
return encodeControlTouchLockMessage(TapAction.SINGLE_TAP, prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_SINGLE_TAP_DISABLED, false));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_DISABLED:
|
||||
return encodeControlTouchLockMessage(TapAction.DOUBLE_TAP, prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_DISABLED, false));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_DISABLED:
|
||||
return encodeControlTouchLockMessage(TapAction.TRIPLE_TAP, prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_DISABLED, false));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_LONG_PRESS_DISABLED:
|
||||
return encodeControlTouchLockMessage(TapAction.LONG_PRESS, prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_LONG_PRESS_DISABLED, false));
|
||||
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_SINGLE_TAP_ACTION_LEFT:
|
||||
pref_string = prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_SINGLE_TAP_ACTION_LEFT, "");
|
||||
return encodeControlFunctionMessage(TapAction.SINGLE_TAP, false, TapFunction.valueOf(pref_string));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_SINGLE_TAP_ACTION_RIGHT:
|
||||
pref_string = prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_SINGLE_TAP_ACTION_RIGHT, "");
|
||||
return encodeControlFunctionMessage(TapAction.SINGLE_TAP, true, TapFunction.valueOf(pref_string));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_ACTION_LEFT:
|
||||
pref_string = prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_ACTION_LEFT, "");
|
||||
return encodeControlFunctionMessage(TapAction.DOUBLE_TAP, false, TapFunction.valueOf(pref_string));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_ACTION_RIGHT:
|
||||
pref_string = prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_DOUBLE_TAP_ACTION_RIGHT, "");
|
||||
return encodeControlFunctionMessage(TapAction.DOUBLE_TAP, true, TapFunction.valueOf(pref_string));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_ACTION_LEFT:
|
||||
pref_string = prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_ACTION_LEFT, "");
|
||||
return encodeControlFunctionMessage(TapAction.TRIPLE_TAP, false, TapFunction.valueOf(pref_string));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_ACTION_RIGHT:
|
||||
pref_string = prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_TRIPLE_TAP_ACTION_RIGHT, "");
|
||||
return encodeControlFunctionMessage(TapAction.TRIPLE_TAP, true, TapFunction.valueOf(pref_string));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_LONG_PRESS_ACTION_LEFT:
|
||||
pref_string = prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_LONG_PRESS_ACTION_LEFT, "");
|
||||
return encodeControlFunctionMessage(TapAction.LONG_PRESS, false, TapFunction.valueOf(pref_string));
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_LONG_PRESS_ACTION_RIGHT:
|
||||
pref_string = prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_CONTROL_LONG_PRESS_ACTION_RIGHT, "");
|
||||
return encodeControlFunctionMessage(TapAction.LONG_PRESS, true, TapFunction.valueOf(pref_string));
|
||||
|
||||
case DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_CONTROL_BUTTON_MODE:
|
||||
AmbientSoundControlButtonMode modes = AmbientSoundControlButtonMode.fromPreferences(prefs.getPreferences());
|
||||
switch (modes) {
|
||||
case NC_AS_OFF:
|
||||
return encodeControlAmbientModeMessage(true, true, true);
|
||||
case NC_AS:
|
||||
return encodeControlAmbientModeMessage(true, true, false);
|
||||
case NC_OFF:
|
||||
return encodeControlAmbientModeMessage(true, false, true);
|
||||
case AS_OFF:
|
||||
return encodeControlAmbientModeMessage(false, true, true);
|
||||
}
|
||||
|
||||
// Miscellaneous Settings
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_WEARING_DETECTION:
|
||||
boolean wearingDetection = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_WEARING_DETECTION, false);
|
||||
return encodeMessage((byte) 0x01, (byte) 0x81, new byte[]{0x00, encodeBoolean(wearingDetection)});
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_WEARING_TONE:
|
||||
boolean wearingTone = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_WEARING_TONE, false);
|
||||
return encodeMessage((byte) 0x01, (byte) 0x8c, new byte[]{0x00, encodeBoolean(wearingTone)});
|
||||
case DeviceSettingsPreferenceConst.PREF_SOUNDCORE_TOUCH_TONE:
|
||||
boolean touchTone = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_TOUCH_TONE, false);
|
||||
return encodeMessage((byte) 0x01, (byte) 0x83, new byte[]{0x00, encodeBoolean(touchTone)});
|
||||
default:
|
||||
LOG.debug("Unsupported CONFIG: " + config);
|
||||
}
|
||||
|
||||
return super.encodeSendConfiguration(config);
|
||||
}
|
||||
|
||||
byte[] encodeDeviceInfoRequest() {
|
||||
byte[] payload = new byte[]{0x00};
|
||||
return encodeMessage((byte) 0x01, (byte) 0x01, payload);
|
||||
}
|
||||
|
||||
byte[] encodeMysteryDataRequest1() {
|
||||
byte[] payload = new byte[]{0x00, 0x00};
|
||||
return encodeMessage((byte) 0x01, (byte) 0x8d, payload);
|
||||
}
|
||||
byte[] encodeMysteryDataRequest2() {
|
||||
byte[] payload = new byte[]{0x00};
|
||||
return encodeMessage((byte) 0x05, (byte) 0x01, payload);
|
||||
}
|
||||
byte[] encodeMysteryDataRequest3() {
|
||||
byte[] payload = new byte[]{0x00, 0x00};
|
||||
return encodeMessage((byte) 0x05, (byte) 0x82, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the following settings to a payload to set the audio-mode on the headphones:
|
||||
* PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL If ANC, Transparent or neither should be active
|
||||
* PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING If the strenght of the ANC should be set manual or adaptively according to ambient noise
|
||||
* PREF_SONY_AMBIENT_SOUND_LEVEL How strong the ANC should be in manual mode
|
||||
* PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE If the Transparency should focus on vocals or should be fully transparent
|
||||
* PREF_SOUNDCORE_WIND_NOISE_REDUCTION If Transparency or ANC should reduce Wind Noise
|
||||
* @return The payload
|
||||
*/
|
||||
private byte[] encodeAudioMode() {
|
||||
Prefs prefs = getDevicePrefs();
|
||||
|
||||
byte anc_mode;
|
||||
switch (prefs.getString(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_AMBIENT_SOUND_CONTROL, "off")) {
|
||||
case "noise_cancelling":
|
||||
anc_mode = 0x00;
|
||||
break;
|
||||
case "ambient_sound":
|
||||
anc_mode = 0x01;
|
||||
break;
|
||||
case "off":
|
||||
anc_mode = 0x02;
|
||||
break;
|
||||
default:
|
||||
LOG.error("Invalid Audio Mode selected");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte anc_strength;
|
||||
switch (prefs.getInt(DeviceSettingsPreferenceConst.PREF_SONY_AMBIENT_SOUND_LEVEL, 0)) {
|
||||
case 0:
|
||||
anc_strength = 0x10;
|
||||
break;
|
||||
case 1:
|
||||
anc_strength = 0x20;
|
||||
break;
|
||||
case 2:
|
||||
anc_strength = 0x30;
|
||||
break;
|
||||
default:
|
||||
LOG.error("Invalid ANC Strength selected");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte adaptive_anc = encodeBoolean(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_ADAPTIVE_NOISE_CANCELLING, true));
|
||||
byte vocal_mode = encodeBoolean(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_TRANSPARENCY_VOCAL_MODE, false));
|
||||
byte windnoise_reduction = encodeBoolean(prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_SOUNDCORE_WIND_NOISE_REDUCTION, false));
|
||||
|
||||
byte[] payload = new byte[]{0x00, anc_mode, anc_strength, vocal_mode, adaptive_anc, windnoise_reduction, 0x01};
|
||||
return encodeMessage((byte) 0x06, (byte) 0x81, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a tap-action
|
||||
* @param action The byte that encodes the action (single/double/triple or long tap)
|
||||
* @param disabled If the action should be enabled or disabled
|
||||
* @return
|
||||
*/
|
||||
private byte[] encodeControlTouchLockMessage(TapAction action, boolean disabled) {
|
||||
boolean enabled = !disabled;
|
||||
byte enabled_byte;
|
||||
byte[] payload;
|
||||
switch (action) {
|
||||
case SINGLE_TAP:
|
||||
case TRIPLE_TAP:
|
||||
enabled_byte = encodeBoolean(enabled);
|
||||
break;
|
||||
case DOUBLE_TAP:
|
||||
case LONG_PRESS:
|
||||
enabled_byte = enabled?(byte) 0x11: (byte) 0x10;
|
||||
break;
|
||||
default:
|
||||
LOG.error("Invalid Tap action");
|
||||
return null;
|
||||
}
|
||||
payload = new byte[]{0x00, 0x00, action.getCode(), enabled_byte};
|
||||
return encodeMessage((byte) 0x04, (byte) 0x83, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a function (eg play/pause) to an action (eg single tap on right bud)
|
||||
* @param action The byte that encodes the action (single/double/triple or long tap)
|
||||
* @param right If the right or left earbud is meant
|
||||
* @param function The byte that encodes the triggered function (eg play/pause)
|
||||
* @return The encoded message
|
||||
*/
|
||||
private byte[] encodeControlFunctionMessage(TapAction action, boolean right, TapFunction function) {
|
||||
byte function_byte;
|
||||
switch (action) {
|
||||
case SINGLE_TAP:
|
||||
case DOUBLE_TAP:
|
||||
function_byte = (byte) (16*6 + function.getCode());
|
||||
break;
|
||||
case TRIPLE_TAP:
|
||||
function_byte = (byte) (16*4 + function.getCode());
|
||||
break;
|
||||
case LONG_PRESS:
|
||||
function_byte = (byte) (16*5 + function.getCode());
|
||||
break;
|
||||
default:
|
||||
LOG.error("Invalid Tap action");
|
||||
return null;
|
||||
}
|
||||
byte[] payload = new byte[] {0x00, encodeBoolean(right), action.getCode(), function_byte};
|
||||
return encodeMessage((byte) 0x04, (byte) 0x81, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes between which Audio Modes a tap should switch, if it is set to switch the Audio Mode.
|
||||
* Zb ANC -> -> Transparency -> Normal -> ANC -> ....
|
||||
*/
|
||||
private byte[] encodeControlAmbientModeMessage(boolean anc, boolean transparency, boolean normal) {
|
||||
// Original app does not allow only one true flag. Unsure if Earbuds accept this state.
|
||||
byte ambientModes = (byte) (4 * (normal?1:0) + 2 * (transparency?1:0) + (anc?1:0));
|
||||
return encodeMessage((byte) 0x06, (byte) 0x82, new byte[] {0x00, ambientModes});
|
||||
}
|
||||
|
||||
private byte encodeBoolean(boolean bool) {
|
||||
if (bool) return 0x01;
|
||||
else return 0x00;
|
||||
}
|
||||
|
||||
private byte[] encodeMessage(byte command1, byte command2, byte[] payload) {
|
||||
int size = 8 + payload.length + 1;
|
||||
ByteBuffer msgBuf = ByteBuffer.allocate(size);
|
||||
msgBuf.order(ByteOrder.BIG_ENDIAN);
|
||||
msgBuf.put(new byte[] {0x08, (byte) 0xee, 0x00, 0x00, 0x00}); // header
|
||||
msgBuf.put(command1);
|
||||
msgBuf.put(command2);
|
||||
msgBuf.put((byte) size);
|
||||
|
||||
msgBuf.put(payload);
|
||||
|
||||
byte checksum = -10;
|
||||
checksum += command1 + command2 + size;
|
||||
for (int b : payload) {
|
||||
checksum += b;
|
||||
}
|
||||
msgBuf.put(checksum);
|
||||
|
||||
return msgBuf.array();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore;
|
||||
|
||||
enum TapAction {
|
||||
SINGLE_TAP((byte) 0x02),
|
||||
DOUBLE_TAP((byte) 0x00),
|
||||
TRIPLE_TAP((byte) 0x05),
|
||||
LONG_PRESS((byte) 0x01)
|
||||
;
|
||||
|
||||
private final byte code;
|
||||
|
||||
TapAction(final byte code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public byte getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package nodomain.freeyourgadget.gadgetbridge.service.devices.soundcore;
|
||||
enum TapFunction {
|
||||
VOLUME_DOWN(1),
|
||||
VOLUME_UP(0),
|
||||
MEDIA_NEXT( 3),
|
||||
MEDIA_PREV(2),
|
||||
PLAYPAUSE(6),
|
||||
VOICE_ASSISTANT(5),
|
||||
AMBIENT_SOUND_CONTROL(4)
|
||||
;
|
||||
|
||||
private final int code;
|
||||
|
||||
TapFunction(final int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
|
@ -81,6 +81,7 @@ public class SleepDetailsParser extends XiaomiActivityParser {
|
|||
|
||||
// Heart rate samples
|
||||
if ((header & (1 << (5 - versionDependentFields))) != 0) {
|
||||
LOG.debug("Heart rate samples from offset {}", Integer.toHexString(buf.position()));
|
||||
final int unit = buf.getShort(); // Time unit (i.e sample rate)
|
||||
final int count = buf.getShort();
|
||||
|
||||
|
@ -98,6 +99,7 @@ public class SleepDetailsParser extends XiaomiActivityParser {
|
|||
|
||||
// SpO2 samples
|
||||
if ((header & (1 << (4 - versionDependentFields))) != 0) {
|
||||
LOG.debug("SpO₂ samples from offset {}", Integer.toHexString(buf.position()));
|
||||
final int unit = buf.getShort(); // Time unit (i.e sample rate)
|
||||
final int count = buf.getShort();
|
||||
|
||||
|
@ -115,6 +117,7 @@ public class SleepDetailsParser extends XiaomiActivityParser {
|
|||
|
||||
// snore samples
|
||||
if (fileId.getVersion() >= 3 && (header & (1 << (3 - versionDependentFields))) != 0) {
|
||||
LOG.debug("Snore level samples from offset {}", Integer.toHexString(buf.position()));
|
||||
final int unit = buf.getShort(); // Time unit (i.e sample rate)
|
||||
final int count = buf.getShort();
|
||||
|
||||
|
@ -131,27 +134,26 @@ public class SleepDetailsParser extends XiaomiActivityParser {
|
|||
}
|
||||
|
||||
final List<XiaomiSleepStageSample> stages = new ArrayList<>();
|
||||
LOG.debug("Sleep stage packets from offset {}", Integer.toHexString(buf.position()));
|
||||
|
||||
// Do not crash if we face a buffer underflow, as the next parsing is not 100% fool-proof,
|
||||
// and we still want to persist whatever we got so far
|
||||
boolean stagesParseFailed = false;
|
||||
try {
|
||||
while (buf.remaining() >= 17 && buf.getInt() == 0xFFFCFAFB) {
|
||||
while (buf.remaining() >= 17) {
|
||||
if (!readStagePacketHeader(buf)) {
|
||||
break;
|
||||
}
|
||||
|
||||
final int headerLen = buf.get() & 0xFF; // this seems to always be 17
|
||||
|
||||
// This timestamp is kind of weird, is seems to sometimes be in seconds
|
||||
// and other times in nanoseconds. Message types 16 and 17 are in seconds
|
||||
final long ts = buf.getLong();
|
||||
final int unk = buf.get() & 0xFF;
|
||||
final int parity = buf.get() & 0xFF; // sum of stage bit count should be uneven
|
||||
final int type = buf.get() & 0xFF;
|
||||
|
||||
final int dataLen = ((buf.get() & 0xFF) << 8) | (buf.get() & 0xFF);
|
||||
|
||||
final byte[] data = new byte[dataLen];
|
||||
buf.get(data);
|
||||
|
||||
final ByteBuffer dataBuf = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN);
|
||||
|
||||
// Known types:
|
||||
// - acc_unk = 0,
|
||||
// - ppg_unk = 1,
|
||||
|
@ -162,6 +164,17 @@ public class SleepDetailsParser extends XiaomiActivityParser {
|
|||
// - Summary = 16,
|
||||
// - Stages = 17
|
||||
|
||||
if (type == 0x2 || type == 0x3 || type == 0x9 || type == 0xc || type == 0xd || type == 0xe || type == 0xf) {
|
||||
// the bytes reserved for the data length are believed to be flags, as they
|
||||
// do not actually have any data following the headers
|
||||
continue;
|
||||
}
|
||||
|
||||
final byte[] data = new byte[dataLen];
|
||||
buf.get(data);
|
||||
|
||||
final ByteBuffer dataBuf = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN);
|
||||
|
||||
if (type == 16) {
|
||||
final int data_0 = dataBuf.get() & 0xFF;
|
||||
final int sleep_index = data_0 >> 4;
|
||||
|
@ -193,11 +206,10 @@ public class SleepDetailsParser extends XiaomiActivityParser {
|
|||
sample.setAwakeDuration(wake_duration);
|
||||
|
||||
// FIXME: This is an array, but we end up persisting only the last sample, since
|
||||
// the timestamp is the primary key
|
||||
// the timestamp is the primary key
|
||||
summaries.add(sample);
|
||||
sample = null;
|
||||
}
|
||||
else if (type == 17) { // Stages
|
||||
} else if (type == 17) { // Stages
|
||||
long currentTime = ts * 1000;
|
||||
for (int i = 0; i < dataLen / 2; i++) {
|
||||
// when the change to the phase occurs
|
||||
|
@ -250,7 +262,6 @@ public class SleepDetailsParser extends XiaomiActivityParser {
|
|||
|
||||
sampleProvider.addSample(summary);
|
||||
}
|
||||
|
||||
} catch (final Exception e) {
|
||||
GB.toast(support.getContext(), "Error saving sleep sample", Toast.LENGTH_LONG, GB.ERROR);
|
||||
LOG.error("Error saving sleep sample", e);
|
||||
|
@ -282,10 +293,23 @@ public class SleepDetailsParser extends XiaomiActivityParser {
|
|||
}
|
||||
}
|
||||
|
||||
return stagesParseFailed;
|
||||
return !stagesParseFailed;
|
||||
}
|
||||
|
||||
static private int decodeStage(int rawStage) {
|
||||
private static boolean readStagePacketHeader(final ByteBuffer buffer) {
|
||||
while (buffer.remaining() >= 17) {
|
||||
if (buffer.getInt() != 0xfffcfafb) {
|
||||
// rollback to second byte of header
|
||||
buffer.position(buffer.position() - 3);
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int decodeStage(int rawStage) {
|
||||
switch (rawStage) {
|
||||
case 0:
|
||||
return 5; // AWAKE
|
||||
|
|
|
@ -302,7 +302,7 @@ public class XiaomiWeatherService extends AbstractXiaomiService {
|
|||
"Unknown" // some string like "Moderate"
|
||||
))
|
||||
.setWarning(XiaomiProto.WeatherWarnings.newBuilder()) // TODO add warnings when they become available through spec
|
||||
.setPressure(weatherSpec.pressure)
|
||||
.setPressure(weatherSpec.pressure * 100f)
|
||||
))
|
||||
.build();
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Collections;
|
|||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -36,134 +37,181 @@ public class ArmenianTransliterator implements Transliterator {
|
|||
// Or if it has 'ւ' symbol after it, then we should read it as 'u' (as double o in booze)
|
||||
private static final Map<String, String> transliterateMap = new LinkedHashMap<String, String>() {
|
||||
{
|
||||
// Simple substitutions
|
||||
Map<String, String> simpleSubstitions = new HashMap<String, String>() {
|
||||
{
|
||||
put("ա","a");
|
||||
put("բ","b");
|
||||
put("գ","g");
|
||||
put("դ","d");
|
||||
put("ե","e");
|
||||
put("զ","z");
|
||||
put("է","e");
|
||||
put("ը","y");
|
||||
put("թ","t");
|
||||
put("ժ","j");
|
||||
put("ի","i");
|
||||
put("լ","l");
|
||||
put("խ","x");
|
||||
put("ծ","c");
|
||||
put("կ","k");
|
||||
put("հ","h");
|
||||
put("ձ","dz");
|
||||
put("ղ","x");
|
||||
put("ճ","c");
|
||||
put("մ","m");
|
||||
put("յ","y");
|
||||
put("ն","n");
|
||||
put("շ","sh");
|
||||
put("չ","ch");
|
||||
put("պ","p");
|
||||
put("ջ","j");
|
||||
put("ռ","r");
|
||||
put("ս","s");
|
||||
put("վ","v");
|
||||
put("տ","t");
|
||||
put("ր","r");
|
||||
put("ց","c");
|
||||
put("փ","p");
|
||||
put("ք","q");
|
||||
put("օ","o");
|
||||
put("և","ev");
|
||||
put("ֆ","f");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Letter + 'ու'
|
||||
put("աու","au");
|
||||
put("բու","bu");
|
||||
put("գու","gu");
|
||||
put("դու","du");
|
||||
put("եու","eu");
|
||||
put("զու","zu");
|
||||
put("էու","eu");
|
||||
put("ըու","yu");
|
||||
put("թու","tu");
|
||||
put("ժու","ju");
|
||||
put("իու","iu");
|
||||
put("լու","lu");
|
||||
put("խու","xu");
|
||||
put("ծու","cu");
|
||||
put("կու","ku");
|
||||
put("հու","hu");
|
||||
put("ձու","dzu");
|
||||
put("ղու","xu");
|
||||
put("ճու","cu");
|
||||
put("մու","mu");
|
||||
put("յու","yu");
|
||||
put("նու","nu");
|
||||
put("շու","shu");
|
||||
put("չու","chu");
|
||||
put("պու","pu");
|
||||
put("ջու","ju");
|
||||
put("ռու","ru");
|
||||
put("սու","su");
|
||||
put("վու","vu");
|
||||
put("տու","tu");
|
||||
put("րու","ru");
|
||||
put("ցու","cu");
|
||||
put("փու","pu");
|
||||
put("քու","qu");
|
||||
put("օու","ou");
|
||||
put("ևու","eu");
|
||||
put("ֆու","fu");
|
||||
put("ոու","vou");
|
||||
char[] letterMapU = {
|
||||
'ա',
|
||||
'բ',
|
||||
'գ',
|
||||
'դ',
|
||||
'ե',
|
||||
'զ',
|
||||
'է',
|
||||
'ը',
|
||||
'թ',
|
||||
'ժ',
|
||||
'ի',
|
||||
'լ',
|
||||
'խ',
|
||||
'ծ',
|
||||
'կ',
|
||||
'հ',
|
||||
'ձ',
|
||||
'ղ',
|
||||
'ճ',
|
||||
'մ',
|
||||
'յ',
|
||||
'ն',
|
||||
'շ',
|
||||
'չ',
|
||||
'պ',
|
||||
'ջ',
|
||||
'ռ',
|
||||
'ս',
|
||||
'վ',
|
||||
'տ',
|
||||
'ր',
|
||||
'ց',
|
||||
'փ',
|
||||
'ք',
|
||||
'օ',
|
||||
'և',
|
||||
'ֆ',
|
||||
'ո',
|
||||
};
|
||||
|
||||
for(char letter : letterMapU) {
|
||||
char capitalLetter = Character.toUpperCase(letter);
|
||||
final String transliteratedLetter = simpleSubstitions.get(Character.toString(letter));
|
||||
final String transliteratedCapitalLetter = simpleSubstitions.get(Character.toString(capitalLetter));
|
||||
|
||||
put(Character.toString(letter) + "ու", transliteratedLetter + "u");
|
||||
put(Character.toString(capitalLetter) + "ու", transliteratedCapitalLetter + "u");
|
||||
|
||||
put(Character.toString(letter) + "ՈՒ", transliteratedLetter + "U");
|
||||
put(Character.toString(capitalLetter) + "ՈՒ", transliteratedCapitalLetter + "U");
|
||||
|
||||
put(Character.toString(letter) + "Ու", transliteratedLetter + "U");
|
||||
put(Character.toString(capitalLetter) + "Ու", transliteratedCapitalLetter + "U");
|
||||
|
||||
put(Character.toString(letter) + "ոՒ", transliteratedLetter + "U");
|
||||
put(Character.toString(capitalLetter) + "ոՒ", transliteratedCapitalLetter + "U");
|
||||
}
|
||||
|
||||
put("ու","u");
|
||||
put("Ու","U");
|
||||
put("ոՒ","U");
|
||||
put("ՈՒ","U");
|
||||
|
||||
// Letter + 'ո'
|
||||
put("բո","bo");
|
||||
put("գո","go");
|
||||
put("դո","do");
|
||||
put("զո","zo");
|
||||
put("թո","to");
|
||||
put("ժո","jo");
|
||||
put("լո","lo");
|
||||
put("խո","xo");
|
||||
put("ծո","co");
|
||||
put("կո","ko");
|
||||
put("հո","ho");
|
||||
put("ձո","dzo");
|
||||
put("ղո","xo");
|
||||
put("ճո","co");
|
||||
put("մո","mo");
|
||||
put("յո","yo");
|
||||
put("նո","no");
|
||||
put("շո","so");
|
||||
put("չո","co");
|
||||
put("պո","po");
|
||||
put("ջո","jo");
|
||||
put("ռո","ro");
|
||||
put("սո","so");
|
||||
put("վո","vo");
|
||||
put("տո","to");
|
||||
put("րո","ro");
|
||||
put("ցո","co");
|
||||
put("փո","po");
|
||||
put("քո","qo");
|
||||
put("ևո","eo");
|
||||
put("ֆո","fo");
|
||||
char[] letterMapVo = {
|
||||
'բ',
|
||||
'գ',
|
||||
'դ',
|
||||
'զ',
|
||||
'թ',
|
||||
'ժ',
|
||||
'լ',
|
||||
'խ',
|
||||
'ծ',
|
||||
'կ',
|
||||
'հ',
|
||||
'ձ',
|
||||
'ղ',
|
||||
'ճ',
|
||||
'մ',
|
||||
'յ',
|
||||
'ն',
|
||||
'շ',
|
||||
'չ',
|
||||
'պ',
|
||||
'ջ',
|
||||
'ռ',
|
||||
'ս',
|
||||
'վ',
|
||||
'տ',
|
||||
'ր',
|
||||
'ց',
|
||||
'փ',
|
||||
'ք',
|
||||
'և',
|
||||
'ֆ',
|
||||
};
|
||||
|
||||
for(char letter : letterMapVo) {
|
||||
char capitalLetter = Character.toUpperCase(letter);
|
||||
final String transliteratedLetter = simpleSubstitions.get(Character.toString(letter));
|
||||
final String transliteratedCapitalLetter = simpleSubstitions.get(Character.toString(capitalLetter));
|
||||
|
||||
put(Character.toString(letter) + "ո", transliteratedLetter + "o");
|
||||
put(Character.toString(capitalLetter) + "ո", transliteratedCapitalLetter + "o");
|
||||
|
||||
put(Character.toString(letter) + "Ո", transliteratedLetter + "Օ");
|
||||
put(Character.toString(capitalLetter) + "Ո", transliteratedCapitalLetter + "Օ");
|
||||
}
|
||||
|
||||
put("ո","vo");
|
||||
put("Ո","VO");
|
||||
|
||||
// Two different ways to write, we support all.
|
||||
put("եւ","ev");
|
||||
put("եվ","ev");
|
||||
|
||||
// Simple substitutions
|
||||
put("ա","a");
|
||||
put("բ","b");
|
||||
put("գ","g");
|
||||
put("դ","d");
|
||||
put("ե","e");
|
||||
put("զ","z");
|
||||
put("է","e");
|
||||
put("ը","y");
|
||||
put("թ","t");
|
||||
put("ժ","j");
|
||||
put("ի","i");
|
||||
put("լ","l");
|
||||
put("խ","x");
|
||||
put("ծ","c");
|
||||
put("կ","k");
|
||||
put("հ","h");
|
||||
put("ձ","dz");
|
||||
put("ղ","x");
|
||||
put("ճ","c");
|
||||
put("մ","m");
|
||||
put("յ","y");
|
||||
put("ն","n");
|
||||
put("շ","sh");
|
||||
put("չ","ch");
|
||||
put("պ","p");
|
||||
put("ջ","j");
|
||||
put("ռ","r");
|
||||
put("ս","s");
|
||||
put("վ","v");
|
||||
put("տ","t");
|
||||
put("ր","r");
|
||||
put("ց","c");
|
||||
put("փ","p");
|
||||
put("ք","q");
|
||||
put("օ","o");
|
||||
put("և","ev");
|
||||
put("ֆ","f");
|
||||
put("Եւ","Ev");
|
||||
put("Եվ","Ev");
|
||||
put("ԵՒ","EV");
|
||||
put("ԵՎ","EV");
|
||||
|
||||
// If this symbol wasn't used in the combination with others, then it's meaningless
|
||||
put("ւ","");
|
||||
put("Ւ","");
|
||||
|
||||
// Add support for capitilazed words
|
||||
for (final Map.Entry<String,String> entry : ((Map<String, String>)this.clone()).entrySet()) {
|
||||
final String capitalKey = WordUtils.capitalize(entry.getKey());
|
||||
if(!capitalKey.equals(entry.getKey())) {
|
||||
put(capitalKey, WordUtils.capitalize(entry.getValue()));
|
||||
}
|
||||
// Simple substitutions have last priority
|
||||
for (final Map.Entry<String,String> entry : simpleSubstitions.entrySet()) {
|
||||
put(entry.getKey(), entry.getValue());
|
||||
put(entry.getKey().toUpperCase(), entry.getValue().toUpperCase());
|
||||
}
|
||||
|
||||
}};
|
||||
|
|
|
@ -2835,4 +2835,121 @@
|
|||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="busy_task_fetch_sports_details_interrupted">تمت مقاطعة جلب التفاصيل الرياضية</string>
|
||||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="unbind_before_pair_title">مرتبط بالفعل</string>
|
||||
<string name="companion_pairing_request_description">إقران هذا الجهاز كمرافق؟.
|
||||
\n
|
||||
\nيوصى بهذا لبعض الوظائف مثل البحث عن الجهاز، ويوفر اتصالاً أفضل.</string>
|
||||
<string name="companion_pairing_request_title">جهاز مرافق</string>
|
||||
<string name="unbind_before_pair_message">هذا الجهاز مرتبط بالفعل بإعدادات Android، مما قد يؤدي إلى فشل الاقتران لبعض الأجهزة.
|
||||
\n
|
||||
\nإذا فشلت إضافة الجهاز، فيرجى إزالته في إعدادات Android والمحاولة مرة أخرى.</string>
|
||||
<string name="devicetype_scannable">جهاز قابل للمسح الضوئي</string>
|
||||
<string name="state_scanned">تم مسحها</string>
|
||||
<string name="devicesetting_scannable_debounce">مهلة الارتداد القابلة للمسح (ثواني)</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">الحد الأدنى لعتبة RSSI للكشف</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">الحد الأدنى للوقت غير المرئي (ثواني)</string>
|
||||
<string name="devicesetting_scannable_debounce_summary">بعد أن يتم فحصه، سيظل الجهاز ممسوحًا ضوئيًا ويتم تجاهله لفترة زمنية محددة</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">بعد أن يتم فحصه، يجب أن يكون الجهاز غير مرئي لهذه الفترة من الوقت قبل أن يتم تسجيله مرة أخرى</string>
|
||||
<string name="devicesetting_scannable_rssi">الحد الأدنى لعتبة RSSI</string>
|
||||
<string name="stepRateSum">مجموع معدل الخطوة</string>
|
||||
<string name="stepRateAvg">متوسط معدل الخطوة</string>
|
||||
<string name="stepLengthAvg">متوسط طول الخطوة</string>
|
||||
<string name="groundContactTimeAvg">متوسط وقت التلامس بالأرض</string>
|
||||
<string name="impactAvg">متوسط الأثر</string>
|
||||
<string name="impactMax">اقصى أثر</string>
|
||||
<string name="swingAngleAvg">متوسط زاوية التأرجح</string>
|
||||
<string name="swolfAvg">متوسط المذؤوب</string>
|
||||
<string name="swolfMax">الحد الأقصى للمذؤوب</string>
|
||||
<string name="swolfMin">الحد الأدنى للمذؤوبين</string>
|
||||
<string name="foreFootLandings">الهبوط الأمامي</string>
|
||||
<string name="midFootLandings">هبوط منتصف القدم</string>
|
||||
<string name="backFootLandings">هبوط القدم الخلفية</string>
|
||||
<string name="eversionAngleAvg">متوسط زاوية الانقلاب</string>
|
||||
<string name="eversionAngleMax">أقصى زاوية للانقلاب</string>
|
||||
<string name="fmtPaceDistance">مسافة الوتيرة %d</string>
|
||||
<string name="fmtPaceType">نوع الوتيرة %d</string>
|
||||
<string name="fmtPacePace">وتيرة %d الوتيرة</string>
|
||||
<string name="fmtPaceCorrection">تصحيح الوتيرة %d</string>
|
||||
<string name="fmtPaceTypeAverage">نوع متوسط السرعة %d</string>
|
||||
<string name="unknownDataEncountered">تمت مواجهة بيانات غير معروفة</string>
|
||||
<string name="milliseconds">ميلي ثانية</string>
|
||||
<string name="degrees">درجة</string>
|
||||
<string name="Pace">وتيره</string>
|
||||
<string name="RunningForm">نموذج الجري</string>
|
||||
<string name="pref_force_enable_spo2_support">دعم قوة SpO2</string>
|
||||
<string name="pref_force_enable_heartrate_support">دعم قوة معدل ضربات القلب</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">قوة تمكين دعم معدل ضربات القلب.
|
||||
\nاستخدام على مسؤوليتك الخاصة</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">فرض تمكين دعم SpO2.
|
||||
\nاستخدام على مسؤوليتك الخاصة</string>
|
||||
<string name="dashboard_settings">إعدادات لوحة القيادة</string>
|
||||
<string name="error_showing_changelog">حدث خطأ أثناء عرض سجل التغيير</string>
|
||||
<string name="activity_type_worn">تم لبسها</string>
|
||||
<string name="bottom_nav_devices">الأجهزة</string>
|
||||
<string name="bottom_nav_dashboard">اللوحة</string>
|
||||
<string name="pref_dashboard_first_title">اظهر اللوحة أولا</string>
|
||||
<string name="pref_dashboard_first_summary">إظهار لوحة المعلومات عند بدء تشغيل Gadgetbridge، بدلاً من شاشة الأجهزة</string>
|
||||
<string name="pref_dashboard_cards_title">عرض الأدوات على البطاقات</string>
|
||||
<string name="pref_dashboard_cards_summary">ارسم بطاقات حول الأدوات على لوحة المعلومات</string>
|
||||
<string name="pref_dashboard_widget_settings">إعدادات الويدجيت</string>
|
||||
<string name="pref_dashboard_widget_today_title">خريطة الأنشطة</string>
|
||||
<string name="pref_dashboard_widget_today_24h_title">وضع 24 ساعة</string>
|
||||
<string name="pref_dashboard_widget_double_size_title">حجم مزدوج</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">عرض الأسطورة</string>
|
||||
<string name="pref_dashboard_widget_goals_chart_title">خريطة الأهداف</string>
|
||||
<string name="pref_dashboard_all_devices_title">جميع الأجهزة</string>
|
||||
<string name="pref_dashboard_select_devices_title">تحديد الأجهزة...</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">حدد الأدوات التي تم تمكينها وبأي ترتيب يتم عرضها على لوحة المعلومات</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">اعرض النشاط في دائرة واحدة مدتها 24 ساعة بدلاً من دائرة مزدوجة مدتها 12 ساعة</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">اسمح للأداة بشغل عمودين على لوحة المعلومات</string>
|
||||
<string name="pref_dashboard_all_devices_summary">قم بدمج بيانات النشاط من كافة الأجهزة المضافة للحصول على الإجماليات على لوحة المعلومات</string>
|
||||
<string name="pref_dashboard_devices_to_include">الأجهزة التي تشمل</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">إظهار وسيلة إيضاح أسفل الأداة تشرح الألوان</string>
|
||||
<string name="pref_dashboard_select_devices_summary">قم بدمج بيانات النشاط من أجهزة محددة للحصول على الإجماليات على لوحة المعلومات</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">الفاصل الزمني لمعدل ضربات القلب</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_summary">مقدار الدقائق التي يظهرها الرسم البياني \"مستهلكة\" بعد كل قياس ناجح لمعدل ضربات القلب</string>
|
||||
<string name="pref_header_generic">نوعي</string>
|
||||
<string name="pref_header_audio">صوت</string>
|
||||
<string name="pref_auto_reply_calls_summary">سوف يقوم الهاتف تلقائيًا باستقبال المكالمات الهاتفية الواردة</string>
|
||||
<string name="pref_auto_reply_calls_title">الرد على المكالمات الهاتفية تلقائيا</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">عدد الثواني التي يتم بعدها الرد على المكالمة تلقائيًا</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">تأخير الرد التلقائي</string>
|
||||
<string name="pref_title_notification_wake_on_open">التنبيه التلقائي وفتح القفل</string>
|
||||
<string name="pref_summary_notification_wake_on_open">قم بتنبيه جهاز Android وإلغاء قفله عندما ترسل الأداة ردًا مفتوحًا. يجب أن تكون في حالة موثوقة.</string>
|
||||
<string name="devicetype_redmi_watch_4">ساعة ريدمي ٤</string>
|
||||
<string name="widget_name_colored_tile">%1$s (إطار ملون)</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">سيتم قراءة الإخطارات بصوت عال من خلال سماعات الرأس</string>
|
||||
<string name="pref_speak_notifications_aloud_title">نطق الإخطارات بصوت عال</string>
|
||||
<string name="widget_layout_top_wide_bot_large">عريضة من الأعلى، كبيرة من الأسفل</string>
|
||||
<string name="widget_layout_top_large_bot_wide">كبير من الاعلى، عريضة من الاسفل</string>
|
||||
<string name="widget_name_untitled">عنصر واجهة المستخدم بدون عنوان (%1$s)</string>
|
||||
<string name="pref_header_calls_and_notifications">المكالمات والإخطارات</string>
|
||||
<string name="armenian">اﻷرمينية</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_off">قم بالتبديل بين الشاشات الرئيسية فقط باستخدام السحب الأفقي</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_summary">في وضع 24 ساعة، ارسم منتصف الليل في الأسفل، ومنتصف النهار في الجزء العلوي من الرسم البياني</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_title">منتصف الليل في الأسفل</string>
|
||||
<string name="pref_title_bottom_navigation_bar">شريط التنقل السفلي</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_on">قم بالتبديل بين الشاشات الرئيسية باستخدام شريط التنقل أو التمرير الأفقي</string>
|
||||
<string name="sleepasandroid_settings">نم كالأندرويد</string>
|
||||
<string name="pref_sleepasandroid_enable_summary">تمكين تكامل Sleep As Android</string>
|
||||
<string name="alarm_slot_reset">تم ضبط فتحة التنبيه على الوضع الافتراضي</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">معدل ضربات القلب</string>
|
||||
<string name="pref_sleepasandroid_device_title">جهاز المزود</string>
|
||||
<string name="pref_sleepasandroid_device_summary">حدد الجهاز كمزود بيانات Sleep As Android</string>
|
||||
<string name="pref_sleepasandroid_features_title">المميزات</string>
|
||||
<string name="pref_sleepasandroid_features_summary">يختلف الدعم من جهاز إلى جهاز</string>
|
||||
<string name="pref_sleepasandroid_feat_alarms">إنذار</string>
|
||||
<string name="pref_sleepasandroid_slot_title">فتحة الإشعارات</string>
|
||||
<string name="pref_sleepasandroid_slot_summary">ما هي فتحة التنبيه التي يجب استخدامها عند ضبط الإشعارات</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">الإشعارات</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">مقياس التسارع</string>
|
||||
<string name="pref_sleepasandroid_feat_oximetry">المقاييس</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SPO2</string>
|
||||
<string name="pref_title_huawei_account">حساب هواوي</string>
|
||||
<string name="pref_summary_huawei_account">حساب هواوي المستخدم في عملية الاقتران. يسمح إعداده بالاقتران دون إعادة ضبط المصنع.</string>
|
||||
<string name="serbian">الصربية</string>
|
||||
<string name="watchface_resolution_doesnt_match">دقة وجه الساعة لا تتطابق مع شاشة الجهاز. واجهة الساعة هي %1$s شاشة الجهاز هي %2$s</string>
|
||||
<string name="cyclingPowerMax">أقصى قوة ركوب الدراجة</string>
|
||||
<string name="cyclingPowerAverage">متوسط قوة ركوب الدراجة</string>
|
||||
<string name="cyclingPowerMin">الحد الأدنى من قوة ركوب الدراجة</string>
|
||||
</resources>
|
|
@ -768,7 +768,7 @@
|
|||
<string name="prefs_find_phone_summary">Verwende dein Band, um den Klingelton deines Telefons wiederzugeben.</string>
|
||||
<string name="prefs_find_phone_duration">Klingeldauer in Sekunden</string>
|
||||
<string name="maximum_duration">Dauer</string>
|
||||
<string name="discovery_need_to_enter_authkey">Dieses Gerät benötigt einen geheimen Authentifikationsschlüssel, den du durch langes Drücken auf den Gerätnamen eingeben kannst. Genaueres im Wiki.</string>
|
||||
<string name="discovery_need_to_enter_authkey">Dieses Gerät benötigt einen geheimen Authentifikationsschlüssel, den du durch langes Drücken auf den Gerätnamen eingeben kannst. Mehr Informationen gibt es auf der Gadgetbride-Webseite.</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip_lite">Du bist dabei, die Firmware %s auf deine Amazfit Bip Lite zu installieren.
|
||||
\n
|
||||
\nBitte stelle sicher, dass du die .fw Datei und danach die .res Datei installierst. Deine Uhr wird nach der Installation der .fw Datei neu gestartet.
|
||||
|
@ -915,7 +915,7 @@
|
|||
<string name="about_description_generic">Cloudloser freier Ersatz für proprietäre Android-Gadget-Apps der Hersteller.</string>
|
||||
<string name="about_activity_title_generic">Über Gadgetbridge</string>
|
||||
<string name="about_title">Über</string>
|
||||
<string name="pref_title_weather_summary">Wird für den LineageOS Wetterdienst genutzt, andere Android-Versionen müssen eine Anwendung wie Weather notification nutzen. Mehr Informationen gibt es im Gadgetbride-Wiki.</string>
|
||||
<string name="pref_title_weather_summary">Wird für den LineageOS Wetterdienst genutzt, andere Android-Versionen müssen eine Anwendung (wie Breezy Weather) nutzen. Mehr Informationen gibt es auf der Gadgetbride-Webseite.</string>
|
||||
<string name="menuitem_worldclock">Weltzeituhr</string>
|
||||
<string name="error_version_check_extreme_caution">ACHTUNG: Fehler beim Prüfen der Information zur Version! Du solltest nicht fortfahren! Versionsname \"%s\" gefunden</string>
|
||||
<string name="permission_granting_mandatory">Alle Berechtigungen sind notwendig und es kann zu Problemen führen, wenn sie nicht genehmigt werden</string>
|
||||
|
@ -1221,7 +1221,7 @@
|
|||
\nHinweis: Du musst .res nicht installieren, wenn es genau die gleiche ist, wie die zuvor installierte.
|
||||
\n
|
||||
\nINSTALLATION AUF EIGENE GEFAHR!</string>
|
||||
<string name="fossil_hr_commute_actions_explanation">Die hier konfigurierten Aktionen werden in der Commute-App auf deiner Uhr angezeigt. Lies das Wiki, um Informationen zum Umgang mit den durch diese Aktionen erzeugten Vorgaben zu erhalten.</string>
|
||||
<string name="fossil_hr_commute_actions_explanation">Die hier konfigurierten Aktionen werden in der Commute-App auf deiner Uhr angezeigt. Mehr Informationen gibt es auf der Gadgetbride-Webseite.</string>
|
||||
<string name="kind_agps_bundle">AGPS-Bundle</string>
|
||||
<string name="qhybrid_calibration_100_steps">100 Schritte</string>
|
||||
<string name="qhybrid_calibration_10_steps">10 Schritte</string>
|
||||
|
@ -1727,7 +1727,7 @@
|
|||
<string name="controlcenter_toggle_details">Details anzeigen</string>
|
||||
<string name="controlcenter_connected_fraction">Verbunden: %d/%d</string>
|
||||
<string name="ukranian">Ukrainisch</string>
|
||||
<string name="info_no_devices_connected">keine Geräte verbunden</string>
|
||||
<string name="info_no_devices_connected">Keine Geräte verbunden</string>
|
||||
<string name="info_connected_count">%d Geräte verbunden</string>
|
||||
<string name="estonian">Estnisch</string>
|
||||
<string name="extended_ascii">Erweitertes ASCII</string>
|
||||
|
@ -1775,7 +1775,7 @@
|
|||
<string name="open_fw_installer_connect_minimum_one_device">Bitte verbinde MINDESTENS EIN Gerät, an das du die Datei senden möchtest.</string>
|
||||
<string name="open_fw_installer_connect_maximum_one_device">Bitte verbinde NUR EIN Gerät, an das du die Datei senden möchtest.</string>
|
||||
<string name="open_fw_installer_ensure_device_connected">Stelle sicher, dass das Gerät %s angeschlossen ist</string>
|
||||
<string name="open_fw_installer_info_text">Mit dem Firmware/Watchface/App/File Installer kannst du unterstützte Dateien (Firmware, Zifferblätter, Anwendungen, GPS, Ressourcen, Schriftarten...) auf das Gerät hochladen/installieren. Weitere Informationen findest du im Wiki: https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Firmware-Update</string>
|
||||
<string name="open_fw_installer_info_text">Mit dem Firmware/Watchface/App/File Installer kannst du unterstützte Dateien (Firmware, Zifferblätter, Anwendungen, GPS, Ressourcen, Schriftarten...) auf das Gerät hochladen/installieren. Mehr Informationen gibt es auf der Gadgetbride-Webseite.</string>
|
||||
<string name="open_fw_installer_getting_files_text">Da wir die Firmware-Dateien nicht verteilen dürfen, musst du dir die Dateien selbst beschaffen. Das bedeutet, dass du nach den Dateien in apk-Dateien, online, in Foren, auf Amazfitwatchfaces (für Miband/Amazfit-Geräte) und so weiter suchen musst.</string>
|
||||
<string name="appmanager_item_outdated">(veraltet)</string>
|
||||
<string name="pref_title_banglejs_txt_bitmap_size">Größe der Text-Bitmaps</string>
|
||||
|
@ -2119,13 +2119,13 @@
|
|||
<string name="devicetype_galaxybuds_2_pro">Galaxy Buds2 Pro</string>
|
||||
<string name="devicetype_soflow_s06">SoFlow SO6</string>
|
||||
<string name="pref_title_lock_unlock">Sperren</string>
|
||||
<string name="pref_header_intent_api">Intent API</string>
|
||||
<string name="pref_header_intent_api">Intent-API</string>
|
||||
<string name="pref_agps_update_time">AGPS Aktualisierungszeit</string>
|
||||
<string name="pref_agps_expire_time">AGPS Ablaufzeit</string>
|
||||
<string name="intent_api_allow_activity_sync_summary">Auslösen der Aktivitätssynchronisierung über die Intent API erlauben</string>
|
||||
<string name="intent_api_allow_activity_sync_summary">Auslösen der Aktivitätssynchronisierung über die Intent-API erlauben</string>
|
||||
<string name="intent_api_allow_activity_sync_title">Aktivitätssynchronisierungsauslöser zulassen</string>
|
||||
<string name="sony_ambient_sound_control_button_modes">Tastenmodi für die Steuerung von Umgebungsgeräuschen</string>
|
||||
<string name="intent_api_allow_trigger_export_summary">Datenbankexport über die Intent API erlauben</string>
|
||||
<string name="intent_api_allow_trigger_export_summary">Datenbankexport über die Intent-API erlauben</string>
|
||||
<string name="intent_api_broadcast_export_summary">Einen Intent via Broadcast verschicken, wenn der Datenbankexport abgeschlossen ist</string>
|
||||
<string name="pref_workout_keep_screen_on_title">Bildschirm während des Trainings eingeschaltet lassen</string>
|
||||
<string name="pref_workout_keep_screen_on_summary">Der Bildschirm bleibt während des Trainings eingeschaltet und die Helligkeit wird angepasst, um die Trainingsdaten in Echtzeit anzuzeigen</string>
|
||||
|
@ -2849,4 +2849,122 @@
|
|||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="busy_task_fetch_sports_details_interrupted">Das Abrufen von Sportdaten wurde unterbrochen</string>
|
||||
<string name="companion_pairing_request_title">Begleitendes Gerät</string>
|
||||
<string name="unbind_before_pair_title">Bereits gebunden</string>
|
||||
<string name="companion_pairing_request_description">Koppelst du dieses Gerät als Begleiter?
|
||||
\n
|
||||
\nDies wird für einige Funktionen empfohlen, z. B. für die Gerätesuche, und bietet eine bessere Verbindung.</string>
|
||||
<string name="unbind_before_pair_message">Dieses Gerät ist bereits in den Android-Einstellungen gebunden, was dazu führen kann, dass die Kopplung bei einigen Geräten fehlschlägt.
|
||||
\n
|
||||
\nWenn das Hinzufügen des Geräts fehlschlägt, entferne es bitte in den Android-Einstellungen und versuche es erneut.</string>
|
||||
<string name="devicetype_scannable">Scannbares Gerät</string>
|
||||
<string name="state_scanned">Gescannt</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">Minimale ungesehene Zeit (Sekunden)</string>
|
||||
<string name="devicesetting_scannable_rssi">Minimaler RSSI-Schwellenwert</string>
|
||||
<string name="devicesetting_scannable_debounce_summary">Nach dem Scannen bleibt das Gerät als gescannt und wird für die angegebene Zeitspanne ignoriert</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">Nach dem Scannen muss das Gerät für diese Zeitspanne unsichtbar sein, bevor es erneut registriert wird</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">Der minimale RSSI-Schwellenwert für die Erkennung</string>
|
||||
<string name="devicesetting_scannable_debounce">Zeitüberschreitung der abtastbaren Entprellung (Sekunden)</string>
|
||||
<string name="stepRateSum">Summe der Schrittgeschwindigkeit</string>
|
||||
<string name="stepRateAvg">Durchschnittliche Schrittfrequenz</string>
|
||||
<string name="stepLengthAvg">Durchschnittliche Schrittlänge</string>
|
||||
<string name="groundContactTimeAvg">Durchschnittliche Bodenkontaktzeit</string>
|
||||
<string name="impactAvg">Durchschnittliche Auswirkungen</string>
|
||||
<string name="impactMax">Maximale Wirkung</string>
|
||||
<string name="swingAngleAvg">Durchschnittlicher Schwenkwinkel</string>
|
||||
<string name="foreFootLandings">Landungen mit dem Vorderfuß</string>
|
||||
<string name="eversionAngleAvg">Durchschnittlicher Eversionswinkel</string>
|
||||
<string name="eversionAngleMax">Maximaler Eversionswinkel</string>
|
||||
<string name="unknownDataEncountered">Unbekannte Daten gefunden</string>
|
||||
<string name="milliseconds">Millisekunden</string>
|
||||
<string name="degrees">Grad</string>
|
||||
<string name="swolfAvg">Mittlerer Swolf</string>
|
||||
<string name="swolfMax">Maximaler Swolf</string>
|
||||
<string name="swolfMin">Minimaler Swolf</string>
|
||||
<string name="backFootLandings">Landungen mit dem Fußrücken</string>
|
||||
<string name="midFootLandings">Landungen mit dem Mittelfuß</string>
|
||||
<string name="pref_force_enable_spo2_support">SpO2-Unterstützung erzwingen</string>
|
||||
<string name="pref_force_enable_heartrate_support">Unterstützung der Herzfrequenz erzwingen</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">Erzwinge die Aktivierung der SpO2-Unterstützung.
|
||||
\nVERWENDUNG AUF EIGENE GEFAHR</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">Erzwinge die Herzfrequenzunterstützung.
|
||||
\nVERWENDUNG AUF EIGENE GEFAHR</string>
|
||||
<string name="error_showing_changelog">Fehler bei der Anzeige des Changelogs</string>
|
||||
<string name="pref_dashboard_widget_goals_chart_title">Zieltabelle</string>
|
||||
<string name="pref_dashboard_all_devices_title">Alle Geräte</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">Wähle, welche Widgets aktiviert sind und in welcher Reihenfolge sie auf dem Dashboard angezeigt werden</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">Zeige die Aktivität in einem einzelnen 24-Stunden-Kreis anstelle eines doppelten 12-Stunden-Kreis</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">Erlaube dem Widget, zwei Spalten auf dem Dashboard einzunehmen</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">Eine Legende unterhalb des Widgets anzeigen, welche die Farben erklärt</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">Herzfrequenz-Intervall</string>
|
||||
<string name="activity_type_worn">Getragen</string>
|
||||
<string name="dashboard_settings">Dashboard-Einstellungen</string>
|
||||
<string name="bottom_nav_dashboard">Dashboard</string>
|
||||
<string name="bottom_nav_devices">Geräte</string>
|
||||
<string name="pref_dashboard_first_title">Dashboard zuerst anzeigen</string>
|
||||
<string name="pref_dashboard_first_summary">Zeige beim Start von Gadgetbridge das Dashboard anstelle des Gerätebildschirms an</string>
|
||||
<string name="pref_dashboard_cards_title">Widgets auf Karten anzeigen</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_summary">Die Anzahl der Minuten, die das Diagramm nach jeder erfolgreichen Herzfrequenzmessung \"Getragen\" anzeigt</string>
|
||||
<string name="pref_dashboard_cards_summary">Zeichne Karten um die Widgets auf dem Dashboard</string>
|
||||
<string name="pref_dashboard_widget_settings">Widget-Einstellungen</string>
|
||||
<string name="pref_dashboard_widget_today_title">Tätigkeitstabelle</string>
|
||||
<string name="pref_dashboard_widget_today_24h_title">24h-Modus</string>
|
||||
<string name="pref_dashboard_widget_double_size_title">Doppelte Größe</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">Legende anzeigen</string>
|
||||
<string name="pref_dashboard_select_devices_title">Geräte auswählen...</string>
|
||||
<string name="pref_dashboard_all_devices_summary">Kombiniere Aktivitätsdaten von allen hinzugefügten Geräten für die Gesamtzahlen auf dem Dashboard</string>
|
||||
<string name="pref_dashboard_select_devices_summary">Kombiniere Aktivitätsdaten von bestimmten Geräten für die Gesamtzahlen auf dem Dashboard</string>
|
||||
<string name="fmtPaceDistance">Tempo %d Entfernung</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">Automatische Antwortverzögerung</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">Anzahl der Sekunden, nach denen der Anruf automatisch entgegengenommen wird</string>
|
||||
<string name="pref_auto_reply_calls_title">Telefonanrufe automatisch annehmen</string>
|
||||
<string name="pref_auto_reply_calls_summary">Das Telefon nimmt eingehende Telefonanrufe automatisch entgegen</string>
|
||||
<string name="pref_dashboard_devices_to_include">Einzubeziehende Geräte</string>
|
||||
<string name="RunningForm">Art der Durchführung</string>
|
||||
<string name="pref_header_audio">Audio</string>
|
||||
<string name="pref_header_generic">Allgemein</string>
|
||||
<string name="pref_title_notification_wake_on_open">Automatisches Aufwachen und Entsperren</string>
|
||||
<string name="pref_summary_notification_wake_on_open">Wecken und Entsperren des Android-Geräts, wenn das Gadget eine OPEN-Antwort zurücksendet. Es muss sich in einem vertrauenswürdigen Zustand befinden.</string>
|
||||
<string name="fmtPaceType">Tempo %d Typ</string>
|
||||
<string name="fmtPacePace">Tempo %d Tempo</string>
|
||||
<string name="fmtPaceCorrection">Tempo %d Korrektur</string>
|
||||
<string name="fmtPaceTypeAverage">Tempo-Typ %d Durchschnitt</string>
|
||||
<string name="Pace">Tempo</string>
|
||||
<string name="widget_name_colored_tile">%1$s (farbige Kachel)</string>
|
||||
<string name="armenian">Armenisch</string>
|
||||
<string name="widget_layout_top_wide_bot_large">Oben weit, unten groß</string>
|
||||
<string name="widget_name_untitled">Unbenanntes Widget (%1$s)</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">Benachrichtigungen werden über die Kopfhörer vorgelesen</string>
|
||||
<string name="pref_speak_notifications_aloud_title">Lautes Sprechen von Benachrichtigungen</string>
|
||||
<string name="pref_header_calls_and_notifications">Anrufe und Benachrichtigungen</string>
|
||||
<string name="devicetype_redmi_watch_4">Redmi Watch 4</string>
|
||||
<string name="widget_layout_top_large_bot_wide">Oben groß, unten weit</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_off">Wechseln zwischen den Hauptbildschirmen nur durch horizontales Wischen</string>
|
||||
<string name="pref_title_bottom_navigation_bar">Untere Navigationsleiste</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_on">Wechsle zwischen den Hauptbildschirmen mit der Navigationsleiste oder durch horizontales Wischen</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_title">Mitternacht ist unten</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_summary">Im 24-Stunden-Modus zeichne Mitternacht unten und Mittag oben im Diagramm</string>
|
||||
<string name="pref_sleepasandroid_device_title">Auszuwählendes Gerät</string>
|
||||
<string name="pref_sleepasandroid_device_summary">Gerät als Sleep as Android-Datenanbieter auswählen</string>
|
||||
<string name="pref_sleepasandroid_features_summary">Die Unterstützung ist von Gerät zu Gerät unterschiedlich</string>
|
||||
<string name="pref_sleepasandroid_feat_alarms">Alarme</string>
|
||||
<string name="alarm_slot_reset">Der Alarm-Platz wurde auf Standard eingestellt</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">Benachrichtigungen</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">Beschleunigungssensor</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">Herzfrequenz</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SpO2</string>
|
||||
<string name="sleepasandroid_settings">Sleep as Android</string>
|
||||
<string name="pref_sleepasandroid_enable_summary">Aktiviere die Integration von Sleep as Android</string>
|
||||
<string name="pref_sleepasandroid_features_title">Eigenschaften</string>
|
||||
<string name="pref_sleepasandroid_slot_title">Alarm-Platz</string>
|
||||
<string name="pref_sleepasandroid_slot_summary">Welcher Alarm-Platz beim Einstellen von Alarmen zu verwenden ist</string>
|
||||
<string name="pref_sleepasandroid_feat_oximetry">Oximetrie</string>
|
||||
<string name="pref_title_huawei_account">Huawei Account</string>
|
||||
<string name="pref_summary_huawei_account">Huawei-Account, welcher für den Kopplungsprozess verwendet wird. Die Einstellung ermöglicht die Kopplung ohne Werksreset.</string>
|
||||
<string name="serbian">Serbisch</string>
|
||||
<string name="watchface_resolution_doesnt_match">Die Auflösung des Watchface stimmt nicht mit dem Bildschirm des Geräts überein. Watchface ist %1$s Gerätebildschirm ist %2$s</string>
|
||||
<string name="cyclingPowerMin">Minimale Leistung beim Radfahren</string>
|
||||
<string name="cyclingPowerMax">Maximale Leistung beim Radfahren</string>
|
||||
<string name="cyclingPowerAverage">Durchschnittliche Leistung beim Radfahren</string>
|
||||
<string name="devicetype_huawei_watchfit2">Huawei Watch Fit 2</string>
|
||||
</resources>
|
|
@ -1766,7 +1766,7 @@
|
|||
<string name="sony_ambient_sound_control_button_modes">Modos del botón de control de sonido ambiente</string>
|
||||
<string name="sony_ambient_sound_control_button_mode_nc_as_off">Cancelación de ruido, sonido ambiente, apagado</string>
|
||||
<string name="sony_ambient_sound_control_button_mode_as_off">Sonido ambiente, apagado</string>
|
||||
<string name="info_no_devices_connected">no hay dispositivos conectados</string>
|
||||
<string name="info_no_devices_connected">Ningún dispositivo conectado</string>
|
||||
<string name="controlcenter_set_folder_title">Establecer o crear una nueva carpeta</string>
|
||||
<string name="autoconnect_from_device_summary">Establecer una conexión cuando ésta es iniciada por un dispositivo, como los auriculares</string>
|
||||
<string name="activity_prefs_allow_bluetooth_intent_api">API Intent de Bluetooth</string>
|
||||
|
@ -2844,4 +2844,122 @@
|
|||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="busy_task_fetch_sports_details_interrupted">Se interrumpió la búsqueda de los detalles deportivos</string>
|
||||
<string name="unbind_before_pair_message">Este dispositivo ya está vinculado en los ajustes de Android, lo que puede hacer que el emparejamiento falle en algunos dispositivos.
|
||||
\n
|
||||
\nSi no se puede añadir el dispositivo, elimínelo de los ajustes de Android y vuelva a intentarlo.</string>
|
||||
<string name="companion_pairing_request_title">Dispositivo complementario</string>
|
||||
<string name="companion_pairing_request_description">¿Empareje este dispositivo como complementario?
|
||||
\n
|
||||
\nSe recomienda para algunas funciones, como buscar dispositivo, y proporciona una mejor conexión.</string>
|
||||
<string name="unbind_before_pair_title">Ya vinculado</string>
|
||||
<string name="devicesetting_scannable_rssi">Umbral mínimo de RSSI</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">Después de ser escaneado, el dispositivo debe permanecer oculto durante este tiempo antes de ser registrado de nuevo</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">El umbral RSSI mínimo para la detección</string>
|
||||
<string name="devicesetting_scannable_debounce">Tiempo de espera para volver a escanear (segundos)</string>
|
||||
<string name="devicetype_scannable">Dispositivo escaneable</string>
|
||||
<string name="state_scanned">Escaneado</string>
|
||||
<string name="devicesetting_scannable_debounce_summary">Después de ser escaneado, el dispositivo permanecerá como escaneado e ignorado durante el tiempo especificado</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">Tiempo mínimo sin ser escaneado (segundos)</string>
|
||||
<string name="swolfAvg">Promedio swolf</string>
|
||||
<string name="swolfMax">Swolf máximo</string>
|
||||
<string name="swolfMin">Swolf mínimo</string>
|
||||
<string name="stepRateSum">Velocidad total de pasos</string>
|
||||
<string name="stepRateAvg">Frecuencia media del paso</string>
|
||||
<string name="stepLengthAvg">Longitud media de los pasos</string>
|
||||
<string name="groundContactTimeAvg">Tiempo medio de la pisada</string>
|
||||
<string name="impactAvg">Promedio de la pisada</string>
|
||||
<string name="impactMax">Pisada máxima</string>
|
||||
<string name="swingAngleAvg">Ángulo promedio de giro</string>
|
||||
<string name="foreFootLandings">Pisadas con el antepié</string>
|
||||
<string name="midFootLandings">Pisadas con el mediopié</string>
|
||||
<string name="backFootLandings">Pisadas con el retropié</string>
|
||||
<string name="eversionAngleAvg">Angulo medio de la eversión</string>
|
||||
<string name="eversionAngleMax">Angulo máximo de la eversión</string>
|
||||
<string name="fmtPaceDistance">Ritmo %d distancia</string>
|
||||
<string name="fmtPaceType">Tipo %d ritmo</string>
|
||||
<string name="fmtPacePace">Ritmo %d</string>
|
||||
<string name="fmtPaceCorrection">Corrección del ritmo %d</string>
|
||||
<string name="fmtPaceTypeAverage">Tipo de ritmo %d medio</string>
|
||||
<string name="unknownDataEncountered">Se encontraron datos desconocidos</string>
|
||||
<string name="milliseconds">milisegundos</string>
|
||||
<string name="degrees">grados</string>
|
||||
<string name="RunningForm">Forma de ejecución</string>
|
||||
<string name="Pace">Ritmo</string>
|
||||
<string name="pref_force_enable_heartrate_support">Forzar soporte de frecuencia cardíaca</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">Forzar habilitar el soporte de frecuencia cardíaca.
|
||||
\nÚSELO BAJO SU PROPIO RIESGO</string>
|
||||
<string name="pref_force_enable_spo2_support">Forzar el soporte de SpO2</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">Forzar la habilitación del soporte de SpO2.
|
||||
\nÚSELO BAJO SU PROPIO RIESGO</string>
|
||||
<string name="error_showing_changelog">Error al mostrar el registro de cambios</string>
|
||||
<string name="dashboard_settings">Ajustes del panel de control</string>
|
||||
<string name="bottom_nav_dashboard">Panel de control</string>
|
||||
<string name="bottom_nav_devices">Dispositivos</string>
|
||||
<string name="pref_dashboard_first_title">Mostrar primero el panel de control</string>
|
||||
<string name="pref_dashboard_first_summary">Mostrar el panel de control cuando se inicia Gadgetbridge, en lugar de la pantalla de dispositivos</string>
|
||||
<string name="pref_dashboard_cards_title">Mostrar widgets en las tarjetas</string>
|
||||
<string name="pref_dashboard_cards_summary">Dibujar tarjetas alrededor de los widgets del panel de control</string>
|
||||
<string name="pref_dashboard_widget_settings">Ajustes del widget</string>
|
||||
<string name="pref_dashboard_widget_today_title">Gráfico de actividad</string>
|
||||
<string name="pref_dashboard_widget_today_24h_title">Modo 24h</string>
|
||||
<string name="pref_dashboard_widget_double_size_title">Tamaño doble</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">Mostrar leyenda</string>
|
||||
<string name="pref_dashboard_widget_goals_chart_title">Gráfico de objetivos</string>
|
||||
<string name="pref_dashboard_devices_to_include">Dispositivos a incluir</string>
|
||||
<string name="pref_dashboard_all_devices_title">Todos los dispositivos</string>
|
||||
<string name="pref_dashboard_select_devices_title">Selecciona los dispositivos...</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">Seleccione qué widgets están activados y en qué orden se muestran en el panel de control</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">Mostrar la actividad en un único círculo de 24h en lugar de un círculo doble de 12h</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">Permitir que el widget ocupe dos columnas en el panel de control</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">Mostrar una leyenda debajo del widget explicando los colores</string>
|
||||
<string name="pref_dashboard_all_devices_summary">Combinar los datos de la actividad de todos los dispositivos añadidos para los totales del panel de control</string>
|
||||
<string name="pref_dashboard_select_devices_summary">Combinar los datos de actividad de dispositivos específicos para los totales del panel de control</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">Intervalo de frecuencia cardíaca</string>
|
||||
<string name="activity_type_worn">Usada</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_summary">La cantidad de minutos que el gráfico muestra \"usado\" después de cada medición correcta de la frecuencia cardíaca</string>
|
||||
<string name="pref_auto_reply_calls_summary">El teléfono descolgará automáticamente las llamadas entrantes</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">Número de segundos tras los cuales se descuelga automáticamente la llamada</string>
|
||||
<string name="pref_auto_reply_calls_title">Responder automáticamente a las llamadas</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">Retraso automático en la respuesta</string>
|
||||
<string name="pref_header_audio">Audio</string>
|
||||
<string name="pref_header_generic">Genérico</string>
|
||||
<string name="pref_summary_notification_wake_on_open">Despierta y desbloquea el dispositivo Android cuando el gadget envía una respuesta ABIERTO de vuelta. Debe estar en un estado de confianza.</string>
|
||||
<string name="pref_title_notification_wake_on_open">Despertador y desbloqueo automáticos</string>
|
||||
<string name="armenian">armenio</string>
|
||||
<string name="widget_layout_top_wide_bot_large">Ancho arriba, grande abajo</string>
|
||||
<string name="widget_layout_top_large_bot_wide">Grande arriba, ancho abajo</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">Las notificaciones se leerán en voz alta a través de los auriculares</string>
|
||||
<string name="pref_speak_notifications_aloud_title">Decir las notificaciones con volumen alto</string>
|
||||
<string name="pref_header_calls_and_notifications">llamadas y notificaciones</string>
|
||||
<string name="pref_title_bottom_navigation_bar">Barra de navegación inferior</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_off">Cambiar entre pantallas principales solo deslizando el dedo horizontalmente</string>
|
||||
<string name="widget_name_colored_tile">%1$s (mosaico de color)</string>
|
||||
<string name="widget_name_untitled">Widget sin título ( %1$s )</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_on">Cambiar entre pantallas principales usando la barra de navegación o deslizando el dedo horizontalmente</string>
|
||||
<string name="devicetype_redmi_watch_4">Redmi Watch 4</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_title">Medianoche en el fondo</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_summary">En el modo 24h, dibuje la medianoche en la parte inferior y el mediodía en la parte superior del gráfico</string>
|
||||
<string name="sleepasandroid_settings">Dormir como Android</string>
|
||||
<string name="pref_sleepasandroid_enable_summary">Habilitar la integración de Sleep As Android</string>
|
||||
<string name="pref_sleepasandroid_device_summary">Seleccione el dispositivo como proveedor de datos de Sleep As Android</string>
|
||||
<string name="pref_sleepasandroid_slot_summary">¿Qué espacio para la alarma se debe utilizar al configurar las alarmas?</string>
|
||||
<string name="pref_sleepasandroid_feat_oximetry">oximetria</string>
|
||||
<string name="pref_sleepasandroid_device_title">Dispositivo del proveedor</string>
|
||||
<string name="pref_sleepasandroid_features_title">Características</string>
|
||||
<string name="pref_sleepasandroid_features_summary">La compatibilidad varía de un dispositivo a otro</string>
|
||||
<string name="pref_sleepasandroid_feat_alarms">Alarmas</string>
|
||||
<string name="alarm_slot_reset">El espacio de la alarma se ha ajustado por defecto</string>
|
||||
<string name="pref_sleepasandroid_slot_title">Espacio de alarmas</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">Notificaciones</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">Acelerómetro</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">Frecuencia cardíaca</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SPO2</string>
|
||||
<string name="pref_title_huawei_account">Cuenta Huawei</string>
|
||||
<string name="pref_summary_huawei_account">Cuenta de Huawei utilizada en el proceso de emparejamiento. Configurarlo permite el emparejamiento sin restablecimiento de fábrica.</string>
|
||||
<string name="serbian">Serbio</string>
|
||||
<string name="watchface_resolution_doesnt_match">La resolución de Watchface no coincide con la pantalla del dispositivo. Watchface es %1$s la pantalla del dispositivo es %2$s</string>
|
||||
<string name="cyclingPowerMin">Potencia mínima del ciclo</string>
|
||||
<string name="devicetype_huawei_watchfit2">Huawei Watch Fit 2</string>
|
||||
<string name="cyclingPowerAverage">Potencia media de ciclo</string>
|
||||
<string name="cyclingPowerMax">Potencia máxima del ciclo</string>
|
||||
</resources>
|
|
@ -2764,4 +2764,134 @@
|
|||
<string name="pref_enable_call_accept">הפעלת קבלת שיחות</string>
|
||||
<string name="pref_heartrate_automatic_enable">הפעלת מדידת דופק אוטומטית</string>
|
||||
<string name="activity_type_roller_skating">החלקה על גלגיליות</string>
|
||||
<string name="devicetype_nothing_cmf_watch_pro">CMF Watch Pro</string>
|
||||
<string name="devicetype_nothingear2">Nothing Ear (2)</string>
|
||||
<string name="pref_header_sony_sound_control">בקרת שמע</string>
|
||||
<string name="pref_wide_area_tap_title">טפיחה באזור רחב</string>
|
||||
<string name="devicetype_nothingearstick">Nothing Ear (Stick)</string>
|
||||
<string name="prefs_active_noise_cancelling_transparency">שקיפות</string>
|
||||
<string name="degrees">מעלות</string>
|
||||
<string name="Pace">צעד</string>
|
||||
<string name="RunningForm">צורת ריצה</string>
|
||||
<string name="pref_wide_area_tap_summary">זיהוי טפיחות בין הלחיים והאוזניים</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">אילוץ הפעלת תמיכה בדופק.
|
||||
\nעל אחריותך בלבד</string>
|
||||
<string name="pref_force_enable_spo2_support">אילוץ תמיכה במדידת חמצן</string>
|
||||
<string name="unbind_before_pair_title">כבר מאוגד</string>
|
||||
<string name="pref_force_enable_heartrate_support">אילוץ תמיכה בדופק</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">אילוץ תמיכה במדידת חמצן בדם.
|
||||
\nלשימוש על אחריותך בלבד</string>
|
||||
<string name="state_scanned">נסרק</string>
|
||||
<string name="weeksleepchart_sleep_a_week_or_month">שינה בשבוע/חודש</string>
|
||||
<string name="pref_header_audio">שמע</string>
|
||||
<string name="weekstepschart_steps_a_week_or_month">צעדים לשבוע/חודש</string>
|
||||
<string name="busy_task_fetch_sports_details_interrupted">משיכת פרטי הספורט נקטעה</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip3">פעולה זו תתקין את הקושחה %s על ה־Amazfit Bip 3 שלך.
|
||||
\n
|
||||
\nנא לוודא את התקנת קושחת ה־.fw בהתחלה, לאחר מכן את קובץ ה־.res השעון שלך יופעל מחדש לאחר התקנת קובץ ה־fw.
|
||||
\n
|
||||
\nלתשומת לבך: אין צורך בהתקנת קובץ ה־.res אם הוא כבר זהה לזה שהתקנת בעבר.
|
||||
\n
|
||||
\nהמשך התהליך הוא על אחריותך!</string>
|
||||
<string name="pref_header_generic">גנרי</string>
|
||||
<string name="pref_title_notification_wake_on_open">התעוררות ושחרור נעילה אוטומטיים</string>
|
||||
<string name="pref_summary_notification_wake_on_open">להעיר ולשחרר את הנעילה של מכשיר ה־Android כשההתקן שולח תגובת פתיחה בחזרה. חייב להיות במצב אמין.</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">השהיית מענה אוטומטי</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">מספר השניות שלאחריהן השיחה תתקבל אוטומטית</string>
|
||||
<string name="pref_auto_reply_calls_title">לענות לשיחות טלפון אוטומטית</string>
|
||||
<string name="pref_auto_reply_calls_summary">הטלפון יקבל שיחות נכנסות אוטומטית</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">משך דופק</string>
|
||||
<string name="pref_dashboard_select_devices_summary">שילוב פעילות מהתקנים מסוימים לסיכומים של לוח הבקרה</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_summary">כמות הדקות שהתרשים מציג ‚נענד’ אחרי כל מדידת דופק מוצלחת</string>
|
||||
<string name="devicetype_amazfit_active_edge">Amazfit Active Edge</string>
|
||||
<string name="devicetype_amazfit_bip3">Amazfit Bip 3</string>
|
||||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="sony_protocol_v2">גרסה 2</string>
|
||||
<string name="sony_protocol_v1">גרסה 1</string>
|
||||
<string name="companion_pairing_request_title">התקן ליווי</string>
|
||||
<string name="zepp_os_watchface_the_ultima">האולטימה</string>
|
||||
<string name="prefs_workmode">מצב עבודה</string>
|
||||
<string name="devicetype_mijia_mho_c303">Mijia MHO-C303</string>
|
||||
<string name="devicetype_sony_linkbuds">Sony LinkBuds</string>
|
||||
<string name="zepp_os_watchface_lightning_flash">הבזק מהבהב</string>
|
||||
<string name="zepp_os_watchface_free_combination">שילוב חופשי</string>
|
||||
<string name="zepp_os_watchface_pure_white">לבן טהור</string>
|
||||
<string name="devicetype_huawei_band8">Huawei Band 8</string>
|
||||
<string name="zepp_os_watchface_starry_sky">ליל כוכבים</string>
|
||||
<string name="devicetype_honor_band5">Honor Band 5</string>
|
||||
<string name="devicetype_honor_band3">Honor Band 3</string>
|
||||
<string name="devicetype_honor_band4">Honor Band 4</string>
|
||||
<string name="sony_protocol_v3">גרסה 3</string>
|
||||
<string name="devicetype_miband8active">Xiaomi Smart Band 8 Active</string>
|
||||
<string name="devicetype_amazfit_balance">Amazfit Balance</string>
|
||||
<string name="devicetype_colacao21">ColaCao 2021</string>
|
||||
<string name="devicetype_colacao23">ColaCao 2023</string>
|
||||
<string name="devicetype_huawei_band_aw70">Huawei Band (AW70)</string>
|
||||
<string name="devicetype_huawei_band6">Huawei Band 6</string>
|
||||
<string name="devicetype_huawei_band7">Huawei Band 7</string>
|
||||
<string name="devicetype_redmi_watch_4">Redmi Watch 4</string>
|
||||
<string name="zepp_os_watchface_vast_sky">שמיים פרוסים</string>
|
||||
<string name="zepp_os_watchface_guider">מנחה</string>
|
||||
<string name="flatDistance">מרחק במישור</string>
|
||||
<string name="huawei_trusleep_title">HUAWEI TruSleep ™</string>
|
||||
<string name="widget_layout_top_wide_bot_large">רחב למעלה, גדול למטה</string>
|
||||
<string name="widget_layout_top_large_bot_wide">גדול למעלה, רחב למטה</string>
|
||||
<string name="widget_name_colored_tile">%1$s (אריח צבעוני)</string>
|
||||
<string name="widget_name_untitled">וידג׳ט ללא שם (%1$s)</string>
|
||||
<string name="pref_force_connection_type_ble">בלוטות׳ LE (אנרגיה נמוכה)</string>
|
||||
<string name="devicetype_honor_magicwatch2">Honor MagicWatch 2</string>
|
||||
<string name="devicetype_amazfit_active">Amazfit Active</string>
|
||||
<string name="devicetype_sony_wi_sp600n">Sony WI-SP600N</string>
|
||||
<string name="devicetype_honor_band6">Honor Band 6</string>
|
||||
<string name="devicetype_honor_band7">Honor Band 7</string>
|
||||
<string name="protocol_version">גרסת פרוטוקול</string>
|
||||
<string name="stepRateSum">סיכום קצב הצעדים</string>
|
||||
<string name="stepRateAvg">קצב צעדים ממוצע</string>
|
||||
<string name="stepLengthAvg">אורך צעד ממוצע</string>
|
||||
<string name="groundContactTimeAvg">זמן מגע ממוצע עם הקרקע</string>
|
||||
<string name="impactAvg">הלימה ממוצעת</string>
|
||||
<string name="impactMax">הלימה מרבית</string>
|
||||
<string name="swingAngleAvg">זווית הנפה ממוצעת</string>
|
||||
<string name="unknownDataEncountered">התגלו נתונים לא מוכרים</string>
|
||||
<string name="milliseconds">מילישניות</string>
|
||||
<string name="bottom_nav_dashboard">לוח בקרה</string>
|
||||
<string name="bottom_nav_devices">התקנים</string>
|
||||
<string name="dashboard_settings">הגדרות לוח בקרה</string>
|
||||
<string name="pref_dashboard_first_title">להציג את לוח הבקרה תחילה</string>
|
||||
<string name="pref_dashboard_first_summary">להציג את לוח הבקרה עם הפעלת Gadgetbridge במקום את מסך ההתקנים</string>
|
||||
<string name="pref_dashboard_widget_today_24h_title">מצב 24 שעות</string>
|
||||
<string name="pref_dashboard_cards_title">הצגת וידג׳טים על הכרטיסים</string>
|
||||
<string name="pref_dashboard_widget_today_title">תרשים פעילות</string>
|
||||
<string name="pref_dashboard_widget_settings">הגדרות וידג׳ט</string>
|
||||
<string name="pref_dashboard_cards_summary">ציור כרטיסים סביב הווידג׳טים בלוח הבקרה</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">הצגת מקרא</string>
|
||||
<string name="pref_dashboard_widget_double_size_title">גודל כפול</string>
|
||||
<string name="pref_dashboard_devices_to_include">התקנים שיש לכלול</string>
|
||||
<string name="pref_dashboard_widget_goals_chart_title">תרשים יעדים</string>
|
||||
<string name="pref_dashboard_all_devices_summary">שילוב נתוני הפעילות מכל ההתקנים שנוספו לסיכומים שבלוח הבקרה</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">הצגת מקרא מתחת לווידג׳ט שמסביר את הצבעים</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">זמן נתק מזערי (שניות)</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">להציג את הפעילות בעיגול אחיד של 24 שעות במקום שני עיגולים של 12 שעות</string>
|
||||
<string name="activity_type_worn">נענד</string>
|
||||
<string name="pref_dashboard_select_devices_title">בחירת התקנים…</string>
|
||||
<string name="pref_dashboard_all_devices_title">כל ההתקנים</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">לאפשר לווידג׳ט לתפוס שתי עמודות בלוח הבקרה</string>
|
||||
<string name="error_showing_changelog">שגיאה בהצגת יומן השינויים</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">סף הקליטה המזערי לזיהוי</string>
|
||||
<string name="devicesetting_scannable_rssi">סף קליטה מזערי</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">לאחר הסריקה, ההתקן צריך להיות בנתק למשך פרק הזמן שהוגדר לפני שיירשם שוב</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">נא לבחור אילו וידג׳טים יופעלו ובאיזה סדר יוצגו בלוח הבקרה</string>
|
||||
<string name="pref_header_calls_and_notifications">שיחות והתראות</string>
|
||||
<string name="pref_speak_notifications_aloud_title">הקראת התראות בקול רם</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">התראות תיקראנה בקול רם דרך האוזניות</string>
|
||||
<string name="armenian">ארמנית</string>
|
||||
<string name="pref_sleepasandroid_device_title">התקן ספק</string>
|
||||
<string name="pref_sleepasandroid_features_summary">התמיכה משתנה מהתקן להתקן</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SpO2</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">דופק</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">מד תאוצה</string>
|
||||
<string name="pref_sleepasandroid_feat_oximetry">מדידת חמצן</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">הודעות</string>
|
||||
<string name="pref_sleepasandroid_features_title">יכולות</string>
|
||||
</resources>
|
File diff suppressed because it is too large
Load Diff
|
@ -1408,7 +1408,7 @@
|
|||
<string name="sony_equalizer_preset_vocal">Vokal</string>
|
||||
<string name="sony_anc_optimizer_status_wearing_condition">Mengukur kondisi pemakaian…</string>
|
||||
<string name="pref_activity_recognize_running">mengenal berlari</string>
|
||||
<string name="info_no_devices_connected">tidak ada perangkat terhubung</string>
|
||||
<string name="info_no_devices_connected">Tidak ada perangkat yang terhubung</string>
|
||||
<string name="info_connected_count">%d perangkat terhubung</string>
|
||||
<string name="watchface_setting_light_up_on_notification">Nyalakan pada notifikasi baru</string>
|
||||
<string name="connection_over_ble">Koneksi melalui BLE</string>
|
||||
|
@ -2831,4 +2831,119 @@
|
|||
<string name="busy_task_fetch_sports_details_interrupted">Pengambilan detail olahraga ditunda</string>
|
||||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="companion_pairing_request_title">Perangkat pendamping</string>
|
||||
<string name="companion_pairing_request_description">Sandingkan perangkat ini sebagai pendamping?
|
||||
\n
|
||||
\nIni disarankan untuk beberapa fungsi seperti cari perangkat, dan menyediakan koneksi yang lebih baik.</string>
|
||||
<string name="unbind_before_pair_title">Sudah tersanding</string>
|
||||
<string name="unbind_before_pair_message">Perangkat ini sudah disandingkan dalam pengaturan Android yang dapat membuat penyandingan gagal untuk beberapa perangkat.
|
||||
\n
|
||||
\nJika penambahan perangkat gagal, silakan hapus dari pengaturan Android dan coba lagi.</string>
|
||||
<string name="devicesetting_scannable_debounce">Waktu habis penghilangan pemindaian (detik)</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">Ambang RSSI minimum untuk deteksi</string>
|
||||
<string name="devicetype_scannable">Perangkat dapat dipindai</string>
|
||||
<string name="state_scanned">Dipindai</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">Waktu tidak terlihat minimum (detik)</string>
|
||||
<string name="devicesetting_scannable_rssi">Ambang RSSI minimal</string>
|
||||
<string name="devicesetting_scannable_debounce_summary">Setelah dipindai, perangkat akan ditetapkan sebagai dipindai dan diabaikan selama waktu yang sudah ditentukan</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">Setelah dipindai, perangkat harus tidak terlihat selama waktu ini sebelum didaftarkan lagi</string>
|
||||
<string name="swolfAvg">Swolf rata-rata</string>
|
||||
<string name="swolfMax">Swolf maksimum</string>
|
||||
<string name="swolfMin">Swolf minimum</string>
|
||||
<string name="stepRateSum">Jumlah laju langkah</string>
|
||||
<string name="stepRateAvg">Laju langkah rata-rata</string>
|
||||
<string name="stepLengthAvg">Panjang Langkah Rata-rata</string>
|
||||
<string name="groundContactTimeAvg">Waktu kontak tanah rata-rata</string>
|
||||
<string name="impactAvg">Dampak rata-rata</string>
|
||||
<string name="impactMax">Dampak maksimum</string>
|
||||
<string name="swingAngleAvg">Sudut ayunan rata-rata</string>
|
||||
<string name="backFootLandings">Landasan kaki belakang</string>
|
||||
<string name="eversionAngleAvg">Sudut eversi rata-rata</string>
|
||||
<string name="eversionAngleMax">Sudut eversi maksimum</string>
|
||||
<string name="fmtPaceDistance">Jarak laju %d</string>
|
||||
<string name="fmtPaceType">Jenis laju %d</string>
|
||||
<string name="fmtPacePace">Laju dalam laju %d</string>
|
||||
<string name="fmtPaceCorrection">Koreksi laju %d</string>
|
||||
<string name="fmtPaceTypeAverage">Rata-rata Jenis Laju %d</string>
|
||||
<string name="unknownDataEncountered">Mendapatkan data tidak diketahui</string>
|
||||
<string name="milliseconds">milidetik</string>
|
||||
<string name="degrees">derajat</string>
|
||||
<string name="Pace">Laju</string>
|
||||
<string name="midFootLandings">Landasan kaki tengah</string>
|
||||
<string name="foreFootLandings">Landasan kaki depan</string>
|
||||
<string name="RunningForm">Bentuk Lari</string>
|
||||
<string name="pref_force_enable_heartrate_support">Paksa dukungan detak jantung</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">Paksa nengaktifkan dukungan detak jantung.
|
||||
\n
|
||||
\nGUNAKAN DENGAN RISIKO ANDA SENDIRI</string>
|
||||
<string name="pref_force_enable_spo2_support">Paksa dukungan SpO2</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">Paksa mengaktifkan dukungan SpO2.
|
||||
\nGUNAKAN DENGAN RISIKO ANDA SENDIRI</string>
|
||||
<string name="activity_type_worn">Dipakai</string>
|
||||
<string name="dashboard_settings">Pengaturan dasbor</string>
|
||||
<string name="bottom_nav_devices">Perangkat</string>
|
||||
<string name="pref_dashboard_first_title">Tampilkan dasbor terlebih dahulu</string>
|
||||
<string name="pref_dashboard_first_summary">Tampilkan dasbor ketika Gadgetbridge dibuka, daripada layar perangkat</string>
|
||||
<string name="pref_dashboard_cards_title">Tampilkan widget pada kartu</string>
|
||||
<string name="pref_dashboard_widget_today_title">Bagan aktivitas</string>
|
||||
<string name="pref_dashboard_widget_today_24h_title">Mode 24j</string>
|
||||
<string name="pref_dashboard_widget_double_size_title">Ukuran ganda</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">Tampilkan legenda</string>
|
||||
<string name="pref_dashboard_widget_goals_chart_title">Bagan capaian</string>
|
||||
<string name="pref_dashboard_devices_to_include">Perangkat untuk disertakan</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">Tampilkan aktivitas dalam lingkaran 24j daripada lingkaran 12j ganda</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">Perbolehkan widget untuk memakai sampai dua kolom di dasbor</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">Tampilkan legenda di bawah widget menjelaskan warnanya</string>
|
||||
<string name="pref_dashboard_all_devices_summary">Gabungkan data aktivitas dari semua perangkat yang ditambahkan untuk jumlah di dasbor</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">Interval detak jantung</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_summary">Jumlah menit bagan menampilkan \'dipakai\' setelah pengukuran detak jantung berhasil</string>
|
||||
<string name="error_showing_changelog">Terjadi kesalahan menampilkan catatan perubahan</string>
|
||||
<string name="bottom_nav_dashboard">Dasbor</string>
|
||||
<string name="pref_dashboard_widget_settings">Pengaturan widget</string>
|
||||
<string name="pref_dashboard_all_devices_title">Semua perangkat</string>
|
||||
<string name="pref_dashboard_select_devices_title">Pilih perangkat...</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">Pilih widget apa saja yang diaktifkan dan dalam urutan yang ditampilkan di dasbor</string>
|
||||
<string name="pref_dashboard_select_devices_summary">Gabungkan data aktivitas dari perangkat tertentu untuk jumlah di dasbor</string>
|
||||
<string name="pref_dashboard_cards_summary">Gambar kartu di sekitar widget dalam dasbor</string>
|
||||
<string name="pref_auto_reply_calls_summary">Ponsel akan mengangkat panggilan masuk secara otomatis</string>
|
||||
<string name="pref_auto_reply_calls_title">Jawab panggilan telepon secara otomatis</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">Detik setelah panggilan diambil secara otomatis</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">Jeda Penjawaban Otomatis</string>
|
||||
<string name="pref_header_audio">Audio</string>
|
||||
<string name="pref_header_generic">Generik</string>
|
||||
<string name="pref_title_notification_wake_on_open">Bangun dan buka kunci otomatis</string>
|
||||
<string name="pref_summary_notification_wake_on_open">Bangun dan buka kunci perangkat Android ketika perangkat mengirim respons OPEN kembali. Perlu dalam keadaan terpercaya.</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">Notifikasi akan dibaca melalui headphone</string>
|
||||
<string name="pref_speak_notifications_aloud_title">Bacakan Notifikasi</string>
|
||||
<string name="devicetype_redmi_watch_4">Redmi Watch 4</string>
|
||||
<string name="widget_layout_top_large_bot_wide">Besar atas, lebar bawah</string>
|
||||
<string name="widget_layout_top_wide_bot_large">Lebar atas, besar bawah</string>
|
||||
<string name="widget_name_colored_tile">%1$s (ubin berwarna)</string>
|
||||
<string name="widget_name_untitled">Widget tidak berjudul (%1$s)</string>
|
||||
<string name="pref_header_calls_and_notifications">Panggilan dan notifikasi</string>
|
||||
<string name="armenian">Armenia</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SPO2</string>
|
||||
<string name="pref_title_huawei_account">Akun Huawei</string>
|
||||
<string name="pref_summary_huawei_account">Akun Huawei digunakan dalam proses penyandingan. Dapat menyandingkan tanpa pengaturan ulang ke pengaturan pabrik.</string>
|
||||
<string name="serbian">Serbia</string>
|
||||
<string name="pref_sleepasandroid_enable_summary">Aktifkan integrasi Sleep As Android</string>
|
||||
<string name="pref_sleepasandroid_device_title">Perangkat penyedia</string>
|
||||
<string name="pref_sleepasandroid_features_summary">Dukungan tergantung pada perangkat</string>
|
||||
<string name="pref_sleepasandroid_slot_title">Slot alarm</string>
|
||||
<string name="pref_sleepasandroid_slot_summary">Slot alarm mana yang digunakan ketika mengatur alarm</string>
|
||||
<string name="alarm_slot_reset">Slot alarm telah diatur menjadi bawaan</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">Notifikasi</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_title">Tengah malam di bawah</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_summary">Dalam mode 24 jam, gambar tengah malam di bawah, tengah hari di atas bagan</string>
|
||||
<string name="sleepasandroid_settings">Sleep As Android</string>
|
||||
<string name="pref_sleepasandroid_device_summary">Pilih perangkat sebagai penyedia data Sleep As Amdroid</string>
|
||||
<string name="pref_sleepasandroid_features_title">Fitur</string>
|
||||
<string name="pref_sleepasandroid_feat_alarms">Alarm</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">Akselerometer</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">Detak jantung</string>
|
||||
<string name="pref_sleepasandroid_feat_oximetry">Oksimetri</string>
|
||||
<string name="pref_title_bottom_navigation_bar">Bilah navigasi bawah</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_on">Ganti antara layar utama menggunakan bilah navigasi atau pengusapan horizontal</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_off">Ganti antara layar utama hanya menggunakan pengusapan horizontal</string>
|
||||
<string name="watchface_resolution_doesnt_match">Resolusi wajah jam tidak cocok dengan layar perangkat. Resolusi wajah jam adalah %1$s dan layar perangkat adalah %2$s</string>
|
||||
</resources>
|
|
@ -52,14 +52,14 @@
|
|||
<!--Strings related to Settings-->
|
||||
<string name="title_activity_settings">Impostazioni</string>
|
||||
<string name="pref_header_general">Impostazioni generali</string>
|
||||
<string name="pref_title_general_autoconnectonbluetooth">Collegati al dispositivo Gadgetbridge quando il Bluetooth viene acceso</string>
|
||||
<string name="pref_title_general_autoconnectonbluetooth">Collegati al/ai dispositivo/i Gadgetbridge quando il Bluetooth viene acceso</string>
|
||||
<string name="pref_title_general_autostartonboot">Avvio automatico</string>
|
||||
<string name="pref_title_general_autoreconnect">Riconnessione automatica</string>
|
||||
<string name="pref_title_audio_player">Riproduttore musicale preferito</string>
|
||||
<string name="pref_default">Predefinito</string>
|
||||
<string name="pref_header_datetime">Data e ora</string>
|
||||
<string name="pref_title_datetime_syctimeonconnect">Sincronizza l\'ora</string>
|
||||
<string name="pref_summary_datetime_syctimeonconnect">Sincronizza l\'orario del dispositivo al collegamento con Gadgetbridge e quando viene cambiata l\'ora o il fuso orario sul dispositivo Android</string>
|
||||
<string name="pref_summary_datetime_syctimeonconnect">Sincronizza l\'orario del/i dispositivo/i al collegamento con Gadgetbridge e quando viene cambiata l\'ora o il fuso orario sul dispositivo e periodicamente</string>
|
||||
<string name="pref_title_theme">Tema</string>
|
||||
<string name="pref_theme_light">Chiaro</string>
|
||||
<string name="pref_theme_dark">Scuro</string>
|
||||
|
@ -1122,7 +1122,7 @@
|
|||
<string name="prefs_events_forwarding_summary">Utilizza gli eventi del dispositivo per avviare azioni e broadcast di Android</string>
|
||||
<string name="seconds_m">sec/m</string>
|
||||
<string name="descentSeconds">Discendente</string>
|
||||
<string name="swolfIndex">Indice SWOLF</string>
|
||||
<string name="swolfIndex">SWOLF</string>
|
||||
<string name="pref_title_lower_button_function_double">Pulsante inferiore, doppio</string>
|
||||
<string name="pref_title_middle_button_function_double">Pulsante centrale, doppio</string>
|
||||
<string name="pref_title_upper_button_function_double">Pulsante superiore, doppio</string>
|
||||
|
@ -2451,4 +2451,235 @@
|
|||
<string name="prefs_wena3_notification_settings_title">Impostazioni Notifiche</string>
|
||||
<string name="devicetype_sony_wf_1000xm5">Sony WF-1000XM5</string>
|
||||
<string name="devicetype_femometer_vinca2">Femometer Vinca II</string>
|
||||
<string name="pai_chart_per_week">PAI settimanale</string>
|
||||
<string name="pai_chart_per_month">PAI mensile</string>
|
||||
<string name="weekstepschart_steps_a_week_or_month">Passi mensili/settimanali</string>
|
||||
<string name="weeksleepchart_sleep_a_week_or_month">Sono mensile/settimanale</string>
|
||||
<string name="dnd_all_day">Tutto il giorno</string>
|
||||
<string name="busy_task_fetch_sports_details_interrupted">Il recupero dei dettagli sportivi è stato interrotto</string>
|
||||
<string name="heartrate_bpm_165">165 bpm</string>
|
||||
<string name="heartrate_bpm_175">175 bpm</string>
|
||||
<string name="heartrate_bpm_185">185 bpm</string>
|
||||
<string name="pref_title_casio_alert_email">Avviso per notifiche e-mail</string>
|
||||
<string name="pref_summary_casio_alert_email">Avviso (vibrazione/bip) per le notifiche via e-mail</string>
|
||||
<string name="pref_title_casio_alert_sms">Avviso per notifiche SMS</string>
|
||||
<string name="pref_summary_casio_alert_sms">Avviso (vibrazione/bip) per le notifiche SMS (messaggi di testo)</string>
|
||||
<string name="pref_title_casio_alert_other">Avviso per altre notifiche</string>
|
||||
<string name="pref_summary_casio_alert_other">Avviso (vibrazione/bip) per le notifiche con altre categorie</string>
|
||||
<string name="busy_task_fetch_pai_data">Recupero dati PAI</string>
|
||||
<string name="manual">Manuale</string>
|
||||
<string name="updatefirmwareoperation_updateproblem_low_battery">Il dispositivo è troppo scarico</string>
|
||||
<string name="clap_hands_to_wakeup_device">Batti le mani per attivare lo schermo</string>
|
||||
<string name="clap_hands_to_wakeup_device_summary">Battere di nuovo le mani spegnerà lo schermo</string>
|
||||
<string name="pixoo_power_saving_summary">Lo schermo si spegnerà se il microfono rileva silenzio per un certo periodo</string>
|
||||
<string name="prefs_wearmode">Modalità uso</string>
|
||||
<string name="wearmode_pebble">Pebble (fibbia per scarpe)</string>
|
||||
<string name="wearmode_necklace">Collana (laccetto collo)</string>
|
||||
<string name="danish">Danese</string>
|
||||
<string name="pref_title_general_reconnectonlytoconnected">Riconnetti solo ai dispositivi collegati</string>
|
||||
<string name="pref_summary_general_reconnectonlytoconnected">Riconnetti solo ai dispositivi collegati, invece di riconnettersi a tutti i dispositivi</string>
|
||||
<string name="pref_title_preview_message_in_title">Mostra anteprima del messaggio nel titolo</string>
|
||||
<string name="pref_summary_preview_message_in_title">Mostra un\'anteprima del messaggio nel titolo di una notifica, come consentito dal dispositivo</string>
|
||||
<string name="pref_title_casio_alert_call">Avviso per chiamate in arrivo</string>
|
||||
<string name="heartrate_bpm_195">195 bpm</string>
|
||||
<string name="wearmode_band">Cinturino (polsino)</string>
|
||||
<string name="pref_title_send_app_notifications">Invia notifiche</string>
|
||||
<string name="pref_summary_send_app_notifications">Inviare le notifiche delle app al dispositivo</string>
|
||||
<string name="alarm_smart_wakeup_interval_default">5 minuti</string>
|
||||
<string name="heartrate_bpm_155">155 bpm</string>
|
||||
<string name="heartrate_bpm_205">205 bpm</string>
|
||||
<string name="prefs_device_name">Nome dispositivo</string>
|
||||
<string name="pref_title_goal_secondary">Obiettivo secondario</string>
|
||||
<string name="pref_summary_casio_alert_call">Avviso (vibrazione/bip) per le chiamate in arrivo</string>
|
||||
<string name="pref_title_casio_alert_calendar">Avviso per notifiche del calendario</string>
|
||||
<string name="pref_summary_casio_alert_calendar">Avviso (vibrazione/bip) per le notifiche del calendario</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip3">Stai per installare il firmware %s sul tuo Amazfit Bip 3.
|
||||
\n
|
||||
\nAssicurati di installare prima il file .fw e dopo il file .res. L\'orologio si riavvierà al termine del caricamento del file .fw.
|
||||
\n
|
||||
\nNota: non è necessario installare il file .res se è uguale a quello installato in precedenza.
|
||||
\n
|
||||
\nPROCEDI A TUO RISCHIO E PERICOLO!</string>
|
||||
<string name="pref_header_generic">Generico</string>
|
||||
<string name="pref_header_audio">Suono</string>
|
||||
<string name="activity_type_darts">Freccette</string>
|
||||
<string name="activity_type_kite_flying">Aquilone</string>
|
||||
<string name="devicetype_miband7pro">Xiaomi Smart Band 7 Pro</string>
|
||||
<string name="devicetype_colacao21">ColaCao 2021</string>
|
||||
<string name="hydration_dnd_summary">Disattivare avvisi di idratazione per un intervallo di tempo</string>
|
||||
<string name="silent_mode_vibrate_silent">Vibrazione / Silenzioso</string>
|
||||
<string name="activity_type_mountain_hike">Escursione in montagna</string>
|
||||
<string name="activity_type_fitness_exercises">Esercizi fitness</string>
|
||||
<string name="activity_type_cross_country_running">Corsa campestre</string>
|
||||
<string name="activity_type_karate">Karate</string>
|
||||
<string name="activity_type_cooldown">Raffreddamento</string>
|
||||
<string name="activity_type_cross_training">Allenamento incrociato</string>
|
||||
<string name="activity_type_plank">Plancia</string>
|
||||
<string name="activity_type_aerobic_exercise">Esercizi aerobici</string>
|
||||
<string name="activity_type_javelin">Giavellotto</string>
|
||||
<string name="activity_type_long_jump">Salto in lungo</string>
|
||||
<string name="activity_type_high_jump">Salto in alto</string>
|
||||
<string name="activity_type_trampoline">Trampolino</string>
|
||||
<string name="activity_type_dumbbell">Pesi</string>
|
||||
<string name="activity_type_tai_chi">Tai chi</string>
|
||||
<string name="activity_type_hula_hooping">Hula hoop</string>
|
||||
<string name="activity_type_disc_sports">Lancio del disco</string>
|
||||
<string name="activity_type_shuttlecock">Volano</string>
|
||||
<string name="activity_type_archery">Tiro con l\'arco</string>
|
||||
<string name="activity_type_softball">Softball</string>
|
||||
<string name="activity_type_sailing">Vela</string>
|
||||
<string name="activity_type_ice_hockey">Hockey su ghiaccio</string>
|
||||
<string name="activity_type_dodgeball">Palla prigioniera</string>
|
||||
<string name="activity_type_skateboarding">Skateboard</string>
|
||||
<string name="activity_type_rock_climbing">Arrampicata su roccia</string>
|
||||
<string name="activity_type_hunting">Caccia</string>
|
||||
<string name="activity_type_trail_run">Corsa su sentiero</string>
|
||||
<string name="devicetype_huawei_watchfit">Huawei Watch Fit</string>
|
||||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="menuitem_zepp_pay">Zepp Pay</string>
|
||||
<string name="zepp_os_watchface_guider">Guida</string>
|
||||
<string name="menuitem_zepp_coach">Zepp Coach</string>
|
||||
<string name="prefs_disconnect_notification_summary">Notifica sul dispositivo quando viene disconnesso dal BT.</string>
|
||||
<string name="prefs_phone_silent_mode">Telefono in silenzioso</string>
|
||||
<string name="pref_do_not_disturb_not_wear">Non disturbare quando non indossato</string>
|
||||
<string name="devicetype_amazfit_bip3">Amazfit Bip 3</string>
|
||||
<string name="devicetype_huawei_talk_band_b6">Huawei Talk Band B6</string>
|
||||
<string name="devicetype_huawei_watchgt2e">Huawei Watch GT 2e</string>
|
||||
<string name="pref_title_notification_wake_on_open">Risveglio e sblocco automatico</string>
|
||||
<string name="pref_summary_notification_wake_on_open">Risveglia e sblocca il dispositivo Android quando il gadget invia una risposta OPEN. Deve essere segnato come affidabile.</string>
|
||||
<string name="activity_type_crossfit">Crossfit</string>
|
||||
<string name="activity_type_functional_training">Allenamento funzionale</string>
|
||||
<string name="activity_type_physical_training">Allenamento fisico</string>
|
||||
<string name="activity_type_taekwondo">Taekwondo</string>
|
||||
<string name="activity_type_fencing">Scherma</string>
|
||||
<string name="activity_type_kendo">Kendo</string>
|
||||
<string name="devicetype_mijia_lywsd03">Sensore di temperatura e umidità Mijia 2</string>
|
||||
<string name="devicetype_mijia_mho_c303">Mijia MHO-C303</string>
|
||||
<string name="devicetype_sony_linkbuds">Sony LinkBuds</string>
|
||||
<string name="devicetype_honor_band3">Honor Band 3</string>
|
||||
<string name="devicetype_honor_band6">Honor Band 6</string>
|
||||
<string name="devicetype_huawei_band8">Huawei Band 8</string>
|
||||
<string name="devicetype_huawei_watch_gt">Huawei Watch GT</string>
|
||||
<string name="devicetype_huawei_band4pro">Huawei Band 4 (Pro)</string>
|
||||
<string name="devicetype_huawei_watchgt3">Huawei Watch GT 3 (Pro)</string>
|
||||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="devicetype_xiaomi_watch_lite">Xiaomi Watch Lite</string>
|
||||
<string name="devicetype_redmiwatch3active">Redmi Watch 3 Active</string>
|
||||
<string name="devicetype_redmiwatch3">Redmi Watch 3</string>
|
||||
<string name="devicetype_redmi_smart_band_2">Redmi Smart Band 2</string>
|
||||
<string name="prefs_heartrate_alert_active_high_threshold">Soglia di allarme per elevata frequenza cardiaca</string>
|
||||
<string name="activity_type_flexibility">Flessibilità</string>
|
||||
<string name="activity_type_track_and_field">Atletica leggera</string>
|
||||
<string name="activity_type_pull_ups">Trazioni</string>
|
||||
<string name="activity_type_jazz_dance">Danza jazz</string>
|
||||
<string name="activity_type_latin_dance">Danza latina</string>
|
||||
<string name="activity_type_kabaddi">Kabaddi</string>
|
||||
<string name="activity_type_mind_and_body">Corpo e mente</string>
|
||||
<string name="activity_type_karting">Go-kart</string>
|
||||
<string name="activity_type_australian_football">Football australiano</string>
|
||||
<string name="activity_type_lacross">Lacrosse</string>
|
||||
<string name="activity_type_shot">Tiro</string>
|
||||
<string name="activity_type_skating">Pattinaggio</string>
|
||||
<string name="devicetype_miband8">Xiaomi Smart Band 8</string>
|
||||
<string name="devicetype_miband8pro">Xiaomi Smart Band 8 Pro</string>
|
||||
<string name="devicetype_honor_magicwatch2">Honor MagicWatch 2</string>
|
||||
<string name="devicetype_huawei_band6">Huawei Band 6</string>
|
||||
<string name="zepp_os_watchface_the_ultima">L\'ultima</string>
|
||||
<string name="devicetype_honor_band4">Honor Band 4</string>
|
||||
<string name="devicetype_honor_band5">Honor Band 5</string>
|
||||
<string name="devicetype_honor_band7">Honor Band 7</string>
|
||||
<string name="silent_mode_normal_silent">Normale / Silenzioso</string>
|
||||
<string name="silent_mode_normal_vibrate">Normale / Vibrazione</string>
|
||||
<string name="activity_type_wrestling">Lotta</string>
|
||||
<string name="devicetype_colacao23">ColaCao 2023</string>
|
||||
<string name="devicetype_miband8active">Xiaomi Smart Band 8 Active</string>
|
||||
<string name="devicetype_huawei_band_aw70">Huawei Band (AW70)</string>
|
||||
<string name="armenian">Armeno</string>
|
||||
<string name="activity_type_indoor_running">Corsa al coperto</string>
|
||||
<string name="activity_type_free_training">Allenamento libero</string>
|
||||
<string name="activity_type_rower">Vogatore</string>
|
||||
<string name="activity_type_stair_stepper">Stepper</string>
|
||||
<string name="activity_type_horizontal_bar">Barre orizzontali</string>
|
||||
<string name="activity_type_parallel_bar">Barre parallele</string>
|
||||
<string name="activity_type_sit_ups">Addominali</string>
|
||||
<string name="activity_type_push_ups">Flessioni</string>
|
||||
<string name="activity_type_battle_rope">Tiro della fune</string>
|
||||
<string name="activity_type_belly_dance">Danza del ventre</string>
|
||||
<string name="activity_type_ballet">Balletto</string>
|
||||
<string name="activity_type_other_dance">Altre danze</string>
|
||||
<string name="activity_type_roller_skating">Pattini a rotelle</string>
|
||||
<string name="activity_type_martial_arts">Arti marziali</string>
|
||||
<string name="activity_type_horse_riding">Equitazione</string>
|
||||
<string name="activity_type_swing">Altalena</string>
|
||||
<string name="activity_type_stairs">Scale</string>
|
||||
<string name="activity_type_fishing">Pesca</string>
|
||||
<string name="activity_type_hand_cycling">Ciclismo manuale</string>
|
||||
<string name="activity_type_billiards">Bigliardo</string>
|
||||
<string name="activity_type_cross_country_skiing">Sci di fondo</string>
|
||||
<string name="activity_type_snow_sports">Sport invernali</string>
|
||||
<string name="activity_type_outdoor_walking">Camminata all\'estero</string>
|
||||
<string name="devicetype_huawei_band7">Huawei Band 7</string>
|
||||
<string name="devicetype_huawei_watchgt2">Huawei Watch GT 2 (Pro)</string>
|
||||
<string name="devicetype_redmi_watch_2">Redmi Watch 2</string>
|
||||
<string name="devicetype_redmi_smart_band_pro">Redmi Smart Band Pro</string>
|
||||
<string name="devicetype_redmi_watch_4">Redmi Watch 4</string>
|
||||
<string name="menuitem_readiness">Preparazione</string>
|
||||
<string name="menuitem_body_composition">Composizione corporea</string>
|
||||
<string name="menuitem_buzzer_intensity">Intensità cicalino</string>
|
||||
<string name="alarm_smart_wakeup_interval">Intervallo di attivazione intelligente:</string>
|
||||
<string name="standing_time">Tempo di riposo</string>
|
||||
<string name="devicetype_redmi_watch_2_lite">Redmi Watch 2 Lite</string>
|
||||
<string name="prefs_password_4_digits_0_to_9_summary">La password deve essere di 4 cifre, utilizzando solo numeri</string>
|
||||
<string name="active_time">Tempo di attività</string>
|
||||
<string name="devicetype_sony_wi_sp600n">Sony WI-SP600N</string>
|
||||
<string name="swolfAvg">Swolf medio</string>
|
||||
<string name="swolfMax">Swolf massimo</string>
|
||||
<string name="swolfMin">Swolf minimo</string>
|
||||
<string name="zepp_os_watchface_lightning_flash">Lampo di luce</string>
|
||||
<string name="yard">iarda</string>
|
||||
<string name="stepLengthAvg">Lunghezza media dei passi</string>
|
||||
<string name="pref_header_sony_sound_control">Controllo sonoro</string>
|
||||
<string name="pai_total">Totale</string>
|
||||
<string name="sony_protocol_v3">Versione 3</string>
|
||||
<string name="protocol_version">Versione protocollo</string>
|
||||
<string name="maxStrokeRate">Frequenza Massima Corse</string>
|
||||
<string name="strokes">Corse Totali</string>
|
||||
<string name="pref_device_action_dnd_off">Non disturbare - Spento</string>
|
||||
<string name="activity_type_curling">Curling</string>
|
||||
<string name="devicetype_nothingear2">Nothing Ear (2)</string>
|
||||
<string name="do_not_disturb_lift_wrist_summary">Solo se l\'attivazione del display al sollevamento è abilitata</string>
|
||||
<string name="sony_protocol_v2">Versione 2</string>
|
||||
<string name="activity_type_pickleball">Pickleball</string>
|
||||
<string name="activity_type_jet_skiing">Moto d\'acqua</string>
|
||||
<string name="activity_type_trekking">Escursionismo</string>
|
||||
<string name="fmtPaceTypeAverage">Tipo di ritmo %d medio</string>
|
||||
<string name="unknownDataEncountered">Dati sconosciuti riscontrati</string>
|
||||
<string name="strokes_minute">serie/min</string>
|
||||
<string name="devicetype_nothingearstick">Nothing Ear (Stick)</string>
|
||||
<string name="devicetype_nothing_cmf_watch_pro">CMF Watch Pro</string>
|
||||
<string name="pai_day">Aumento giornaliero</string>
|
||||
<string name="sony_protocol_v1">Versione 1</string>
|
||||
<string name="activity_type_smith_machine">Macchina Smith</string>
|
||||
<string name="zepp_os_watchface_free_combination">Combinazione libera</string>
|
||||
<string name="zepp_os_watchface_city_of_speed">Città di velocità</string>
|
||||
<string name="avgStrokeRate">Frequenza Media Corse</string>
|
||||
<string name="stepRateAvg">Velocità media dei passi</string>
|
||||
<string name="eversionAngleAvg">Angolo medio di estroflessione</string>
|
||||
<string name="eversionAngleMax">Angolo massimo di estroflessione</string>
|
||||
<string name="fmtPaceDistance">Ritmo %d distanza</string>
|
||||
<string name="fmtPaceType">Tipo %d ritmo</string>
|
||||
<string name="fmtPacePace">Ritmo %d</string>
|
||||
<string name="fmtPaceCorrection">Correzione ritmo %d</string>
|
||||
<string name="milliseconds">millisecondi</string>
|
||||
<string name="degrees">gradi</string>
|
||||
<string name="pref_device_action_dnd_priority">Non disturbare - Solo priorità</string>
|
||||
<string name="pref_device_action_dnd_alarms">Non disturbare - Solo sveglie</string>
|
||||
<string name="pref_device_action_dnd_on">Non disturbare - Acceso</string>
|
||||
<string name="huawei_trusleep_title">HUAWEI TruSleep ™</string>
|
||||
<string name="prefs_workmode">Modalità lavoro</string>
|
||||
<string name="flatDistance">Distanza piana</string>
|
||||
<string name="prefs_active_noise_cancelling_transparency">Trasparenza</string>
|
||||
<string name="laneLength">Lunghezza Corsia</string>
|
||||
<string name="stepRateSum">Velocità totale dei passi</string>
|
||||
<string name="Pace">Ritmo</string>
|
||||
</resources>
|
File diff suppressed because it is too large
Load Diff
|
@ -1728,7 +1728,7 @@
|
|||
<string name="prefs_password_summary">Vergrendel de band met een wachtwoord wanneer deze van de pols wordt verwijderd</string>
|
||||
<string name="prefs_password_enabled">Wachtwoord ingeschakeld</string>
|
||||
<string name="prefs_password_4_digits_1_to_4_summary">Het wachtwoord moet 4 cijfers hebben, met de nummers 1 tot en met 4</string>
|
||||
<string name="info_no_devices_connected">geen apparaten aangesloten</string>
|
||||
<string name="info_no_devices_connected">Geen apparaten aangesloten</string>
|
||||
<string name="pref_blacklist_calendars_summary">Agenda\'s op de zwarte lijst worden niet gesynchroniseerd met het apparaat</string>
|
||||
<string name="bengali">Bengaals</string>
|
||||
<string name="czech">Tsjechisch</string>
|
||||
|
@ -2832,13 +2832,127 @@
|
|||
<string name="pref_adaptive_volume_control_summary">Verhoog volume automatisch bij veel omgevingsgeluid</string>
|
||||
<string name="pref_header_sony_sound_control">Geluidsinstellingen</string>
|
||||
<string name="error_scan_failed">Scan mislukt: %d</string>
|
||||
<string name="scan_scanning_all_devices">Scannen voor alle apparaten</string>
|
||||
<string name="scan_scanning_all_devices">Scannen naar alle apparaten</string>
|
||||
<string name="scan_not_scanning">Niet aan het scannen</string>
|
||||
<string name="scan_scanning_single_device">Scannen voor 1 apparaat</string>
|
||||
<string name="scan_scanning_multiple_devices">Scannen voor %d apparaten</string>
|
||||
<string name="scan_scanning_single_device">Scannen naar 1 apparaat</string>
|
||||
<string name="scan_scanning_multiple_devices">Scannen naar %d apparaten</string>
|
||||
<string name="notification_channel_scan_service_name">Scan-service</string>
|
||||
<string name="device_state_waiting_scan">Wachten op apparaatscan</string>
|
||||
<string name="devicetype_miband8active">Xiaomi Smart Band 8 Active</string>
|
||||
<string name="alarm_smart_wakeup_interval_default">5 minuten</string>
|
||||
<string name="alarm_smart_wakeup_interval">Interval slim wekken:</string>
|
||||
<string name="companion_pairing_request_title">Bijbehorend apparaat</string>
|
||||
<string name="unbind_before_pair_title">Al gekoppeld</string>
|
||||
<string name="unbind_before_pair_message">Dit apparaat is al gekoppeld aan de Android-instellingen, waardoor het koppelen op sommige apparaten kan mislukken.
|
||||
\n
|
||||
\nAls het toevoegen van het apparaat mislukt, verwijder het dan in de Android-instellingen en probeer het opnieuw.</string>
|
||||
<string name="companion_pairing_request_description">Koppel je dit apparaat als begeleider?
|
||||
\n
|
||||
\nDit wordt aanbevolen voor sommige functies zoals zoeken naar apparaten en biedt een betere verbinding.</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">Na te zijn gevonden, moet het apparaat deze tijd buiten bereik zijn om opnieuw gevonden te kunnen worden</string>
|
||||
<string name="devicetype_scannable">Scanbaar apparaat</string>
|
||||
<string name="state_scanned">Gescand</string>
|
||||
<string name="devicesetting_scannable_debounce">Seconden zichtbaar na gescand</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">Seconden afwezig na niet gescand</string>
|
||||
<string name="devicesetting_scannable_rssi">Minimaal RSSI-niveau</string>
|
||||
<string name="devicesetting_scannable_debounce_summary">Na te zijn gevonden, blijft het apparaat deze tijd actief als gescand en wordt verder genegeerd</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">Het minimale RSSI-niveau om gevonden te kunnen worden</string>
|
||||
<string name="pref_force_enable_heartrate_support">Forceer hartslagmeting</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">Forceer ondersteuning van hartslagmeting
|
||||
\nGEBRUIK OP EIGEN RISICO</string>
|
||||
<string name="pref_force_enable_spo2_support">Forceer SpO2-ondersteuning</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">Forceer ondersteuning van bloedzuurstofmetingen
|
||||
\nGEBRUIK OP EIGEN RISICO</string>
|
||||
<string name="error_showing_changelog">Fout bij tonen wijzigingenlijst</string>
|
||||
<string name="activity_type_worn">Gedragen</string>
|
||||
<string name="bottom_nav_dashboard">Dashboard</string>
|
||||
<string name="pref_dashboard_first_title">Toon dashboard eerst</string>
|
||||
<string name="pref_dashboard_first_summary">Toon het dashboard wanneer Gadgetbridge opstart, in plaats van het apparatenscherm</string>
|
||||
<string name="pref_dashboard_cards_title">Widgets op kaarten</string>
|
||||
<string name="pref_dashboard_widget_settings">Widget-instellingen</string>
|
||||
<string name="pref_dashboard_widget_double_size_title">Dubbele grootte</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">Toon legenda</string>
|
||||
<string name="pref_dashboard_widget_goals_chart_title">Doelen-diagram</string>
|
||||
<string name="pref_dashboard_devices_to_include">Apparaten</string>
|
||||
<string name="pref_dashboard_all_devices_title">Alle apparaten</string>
|
||||
<string name="pref_dashboard_select_devices_title">Selecteer apparaten...</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">Selecteer welke widgets op het dashboard getoond worden en in welke volgorde</string>
|
||||
<string name="pref_dashboard_all_devices_summary">Combineer activiteitsgegevens van alle toegevoegde apparaten voor het dashboard</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">Toon de activiteit in een enkele 24-uurscirkel in plaats van een dubbele 12-uurscirkel</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">Toon een legenda onder de widget om de kleuren uit te leggen</string>
|
||||
<string name="pref_dashboard_select_devices_summary">Combineer activiteitsgegevens van specifieke apparaten voor het dashboard</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">Interval hartslagmeting</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_summary">Het aantal minuten dat het diagram \'gedragen\' toont na elke succesvolle hartslagmeting</string>
|
||||
<string name="pref_auto_reply_calls_summary">De telefoon neemt binnenkomende telefoongesprekken automatisch op</string>
|
||||
<string name="pref_auto_reply_calls_title">Binnenkomende gesprekken automatisch opnemen</string>
|
||||
<string name="dashboard_settings">Dashboard-instellingen</string>
|
||||
<string name="bottom_nav_devices">Apparaten</string>
|
||||
<string name="pref_dashboard_cards_summary">Toon de widgets op kaarten op het dashboard</string>
|
||||
<string name="pref_dashboard_widget_today_title">Activiteit-diagram</string>
|
||||
<string name="pref_dashboard_widget_today_24h_title">24-uursmodus</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">Sta de widget toe om twee kolommen van het dashboard te gebruiken</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">Aantal seconden waarna een binnenkomend telefoongesprek automatisch opgenomen wordt</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">Vertraging automatisch opnemen</string>
|
||||
<string name="swolfAvg">Gemiddelde SWOLF</string>
|
||||
<string name="swolfMax">Maximale SWOLF</string>
|
||||
<string name="swolfMin">Minimale SWOLF</string>
|
||||
<string name="stepRateSum">Opgetelde stapsnelheid</string>
|
||||
<string name="stepRateAvg">Gemiddelde stapsnelheid</string>
|
||||
<string name="stepLengthAvg">Gemiddelde staplengte</string>
|
||||
<string name="groundContactTimeAvg">Gemiddelde contacttijd met grond</string>
|
||||
<string name="impactAvg">Gemiddelde impact</string>
|
||||
<string name="impactMax">Maximale impact</string>
|
||||
<string name="swingAngleAvg">Gemiddelde zwaaihoek</string>
|
||||
<string name="foreFootLandings">Voorvoetlandingen</string>
|
||||
<string name="midFootLandings">Midvoetlandingen</string>
|
||||
<string name="backFootLandings">Hiellandingen</string>
|
||||
<string name="eversionAngleAvg">Gemiddelde eversiehoek</string>
|
||||
<string name="eversionAngleMax">Maximale eversiehoek</string>
|
||||
<string name="fmtPaceDistance">Tempo %d afstand</string>
|
||||
<string name="fmtPaceType">Tempo %d type</string>
|
||||
<string name="fmtPacePace">Tempo %d tempo</string>
|
||||
<string name="fmtPaceCorrection">Tempo %d correctie</string>
|
||||
<string name="fmtPaceTypeAverage">Tempotype %d gemiddelde</string>
|
||||
<string name="unknownDataEncountered">Niet-herkende gegevens aangetroffen</string>
|
||||
<string name="milliseconds">milliseconden</string>
|
||||
<string name="degrees">graden</string>
|
||||
<string name="Pace">Tempo</string>
|
||||
<string name="RunningForm">Hardloopkwaliteit</string>
|
||||
<string name="pref_header_audio">Audio</string>
|
||||
<string name="pref_header_generic">Algemeen</string>
|
||||
<string name="pref_title_notification_wake_on_open">Automatisch ontgrendelen</string>
|
||||
<string name="pref_summary_notification_wake_on_open">Ontgrendel het scherm van het Android-apparaat wanneer de gadget een OPEN-commando stuurt. Werkt alleen wanneer vertrouwde ontgrendeling actief is.</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">Meldingen zullen opgelezen worden via de koptelefoon</string>
|
||||
<string name="pref_speak_notifications_aloud_title">Meldingen oplezen</string>
|
||||
<string name="devicetype_redmi_watch_4">Redmi Watch 4</string>
|
||||
<string name="widget_name_untitled">Widget zonder titel (%1$s)</string>
|
||||
<string name="pref_header_calls_and_notifications">Gesprekken en meldingen</string>
|
||||
<string name="widget_layout_top_wide_bot_large">Breed boven, groot onder</string>
|
||||
<string name="widget_layout_top_large_bot_wide">Groot boven, breed onder</string>
|
||||
<string name="widget_name_colored_tile">%1$s (gekleurde titel)</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_summary">Toon in 24-uursmodus middernacht onderaan en 12 uur bovenaan de cirkel</string>
|
||||
<string name="sleepasandroid_settings">Sleep As Android</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_off">Wissel tussen de hoofdschermen alleen met horizontaal vegen</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_title">Middernacht onderaan</string>
|
||||
<string name="pref_sleepasandroid_device_title">Gekoppeld apparaat</string>
|
||||
<string name="pref_sleepasandroid_device_summary">Selecteer apparaat als databron voor Sleep As Android</string>
|
||||
<string name="pref_sleepasandroid_features_title">Functies</string>
|
||||
<string name="pref_sleepasandroid_features_summary">Ondersteuning verschilt per apparaat</string>
|
||||
<string name="pref_sleepasandroid_feat_alarms">Wekkers</string>
|
||||
<string name="pref_sleepasandroid_slot_summary">Welk wekkerslot wordt gebruikt voor het instellen van wekkers</string>
|
||||
<string name="pref_sleepasandroid_slot_title">Wekkerslot</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">Bewegingssensor</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">Hartslag</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SpO2</string>
|
||||
<string name="pref_sleepasandroid_enable_summary">Integratie met Sleep As Android inschakelen</string>
|
||||
<string name="alarm_slot_reset">Wekkerslot is teruggezet naar standaard</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">Meldingen</string>
|
||||
<string name="pref_sleepasandroid_feat_oximetry">Bloedzuurstof</string>
|
||||
<string name="armenian">Armeens</string>
|
||||
<string name="pref_title_bottom_navigation_bar">Navigatiebalk onderaan</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_on">Wissel tussen de hoofdschermen met de navigatiebalk of horizontaal vegen</string>
|
||||
<string name="pref_title_huawei_account">Huawei-account</string>
|
||||
<string name="serbian">Servisch</string>
|
||||
<string name="pref_summary_huawei_account">Huawei-account dat gebruikt is tijdens het bindingsproces. Het hier instellen staat toe dat het apparaat gebonden kan worden zonder reset naar fabrieksinstellingen.</string>
|
||||
<string name="watchface_resolution_doesnt_match">Resolutie van wijzerplaat komt niet overeen met het scherm van het apparaat. Wijzerplaat is %1$s en scherm is %2$s</string>
|
||||
</resources>
|
|
@ -766,7 +766,7 @@
|
|||
<string name="prefs_find_phone_duration">Duração do toque sonoro em segundos</string>
|
||||
<string name="maximum_duration">Duração</string>
|
||||
<string name="discovery_need_to_enter_authkey">Esse dispositivo precisa de sua chave de autenticação secreta, realize pressionamento longo no dispositivo para inseri-lo. Leia o wiki.</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip_lite">Você está prestes a instalar o firmware %s no seu Amazit Bip Lite.
|
||||
<string name="fw_upgrade_notice_amazfitbip_lite">Você está prestes a instalar o firmware %s no seu Amazfit Bip Lite.
|
||||
\n
|
||||
\nCertifique-se de instalar o arquivo .fw, e depois o arquivo .res. Seu relógio será reiniciado após a instalação do arquivo .fw.
|
||||
\n
|
||||
|
@ -1510,7 +1510,7 @@
|
|||
<string name="about_description_banglejs_nightly">Aplicativo companheiro Android para Bangle.js construído em cima do projeto Gadgetbridge, com acesso adicional à Internet.
|
||||
\n
|
||||
\nDevido às políticas Google Play Store, não somos permitidos ter um link de doação no próprio aplicativo, mas se você gosta deste aplicativo, por favor, considere doar através da página inicial do Gadgetbridge abaixo.</string>
|
||||
<string name="single_band">Banda única</string>
|
||||
<string name="single_band">Single Band</string>
|
||||
<string name="about_activity_title_banglejs_nightly">Sobre o Bangle.js Gadgetbridge (Nightly)</string>
|
||||
<string name="power_saving">Economia de energia</string>
|
||||
<string name="gadgetbridge_running_banglejs_nightly">Nightly Bangle.js em execução</string>
|
||||
|
@ -1519,4 +1519,92 @@
|
|||
<string name="action_changelog">Registro de mudanças</string>
|
||||
<string name="custom">Personalizado</string>
|
||||
<string name="application_name_banglejs_nightly">Bangle.js Gadgetbridge (Nightly)</string>
|
||||
<string name="pref_header_health">Saúde</string>
|
||||
<string name="error_showing_changelog">Erro ao exibir o registro de alterações</string>
|
||||
<string name="appmanager_watchface_activate">Ativar</string>
|
||||
<string name="pref_header_audio">Áudio</string>
|
||||
<string name="pref_header_generic">Genérico</string>
|
||||
<string name="pref_title_mb_intents">Transmitir diretamente as intenções dos botões de mídia</string>
|
||||
<string name="pref_summary_mb_intents">Ative se o controle de mídia do dispositivo não estiver funcionando para determinados aplicativos</string>
|
||||
<string name="pref_theme_dynamic">Cores dinâmicas</string>
|
||||
<string name="pref_show_changelog_summary">Exibir o registro de alterações desde a última versão após a atualização do Gadgetbridge</string>
|
||||
<string name="accuracy_first">Precisão primeiro</string>
|
||||
<string name="speed_first">Velocidade primeiro</string>
|
||||
<string name="pref_show_changelog">Mostrar registro de alterações na inicialização</string>
|
||||
<string name="steps_streaks">Sequência de passos</string>
|
||||
<string name="step_streak_total">Total</string>
|
||||
<string name="steps_streaks_average_steps">Média de
|
||||
\npassos</string>
|
||||
<string name="steps_streaks_achievement_rate">Taxa de
|
||||
\nconquista</string>
|
||||
<string name="steps_streaks_total_steps_hint_totals">Número total de passos já registrados</string>
|
||||
<string name="step_streaks_achievements_sharing_title">Conquistas de passos</string>
|
||||
<string name="changelog_show_full">Mais…</string>
|
||||
<string name="uploadwatchfaceoperation_in_progress">Carregando o watchface</string>
|
||||
<string name="steps_streaks_total_steps_hint">Número total de passos em toda a sequência</string>
|
||||
<string name="steps_streaks_total_steps_average_hint">Média total de %d passos por dia</string>
|
||||
<string name="step_streak_days_hint">Número de dias consecutivos em que a meta de passos foi atingida</string>
|
||||
<string name="steps_streaks_hint">Sequência de dias consecutivos sem interrupção com metas de passos sendo alcançadas</string>
|
||||
<string name="uploading_watchface">Carregando o watchface…</string>
|
||||
<string name="step_streak_longest">Mais longo</string>
|
||||
<string name="appmanager_app_share">Compartilhar</string>
|
||||
<string name="debugactivity_confirm_remove_device_preferences_title">Remover as preferências do dispositivo?</string>
|
||||
<string name="debugactivity_confirm_remove_device_preferences">Isso redefinirá as preferências do dispositivo para todos os dispositivos conectados. Tem certeza?</string>
|
||||
<string name="pref_header_calendar">Calendário</string>
|
||||
<string name="pref_title_general_reconnectonlytoconnected">Reconectar somente a dispositivos conectados</string>
|
||||
<string name="pref_summary_general_reconnectonlytoconnected">Reconectar somente a dispositivos conectados, em vez de reconectar a todos os dispositivos</string>
|
||||
<string name="steps_streaks_total_steps">Passos
|
||||
\ntotais</string>
|
||||
<string name="steps_streaks_streak_days">Dias
|
||||
\nseguidos</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip3pro">Você está prestes a instalar o firmware %s no seu Amazfit Bip 3 Pro.
|
||||
\n
|
||||
\nCertifique-se de instalar o arquivo .fw, e depois o arquivo .res. Seu relógio será reiniciado após a instalação do arquivo .fw.
|
||||
\n
|
||||
\nNota: você não precisa instalar .res se esse arquivo for exatamente o mesmo que os instalados anteriormente.
|
||||
\n
|
||||
\nPROSSIGA POR SUA CONTA E RISCO!</string>
|
||||
<string name="open_fw_installer_select_file">Selecione um arquivo que deseja enviar para o dispositivo: %s</string>
|
||||
<string name="pref_header_display">Exibir</string>
|
||||
<string name="step_streak_average_steps_hint">Média de passos por dia da sequência</string>
|
||||
<string name="appmanager_app_start">Iniciar</string>
|
||||
<string name="appmanager_app_download">Download para o cache</string>
|
||||
<string name="appmanager_item_outdated">(desatualizado)</string>
|
||||
<string name="appmanager_download_started">Download do aplicativo iniciado</string>
|
||||
<string name="pref_header_connection">Conexão</string>
|
||||
<string name="step_streak_ongoing">Em andamento</string>
|
||||
<string name="pref_title_navigation_prefs">Preferências de navegação</string>
|
||||
<string name="pref_sleepasandroid_features_title">Recursos</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">Frequência cardíaca</string>
|
||||
<string name="pref_summary_huawei_account">Conta da Huawei usada no processo de emparelhamento. Sua configuração permite emparelhar sem redefinição de fábrica.</string>
|
||||
<string name="pref_header_time">Hora</string>
|
||||
<string name="steps_streaks_total_days_hint_totals">Porcentagem de dias com meta atingida em relação a todos os dias com passos</string>
|
||||
<string name="pref_cache_weather">Informações sobre o clima em cache</string>
|
||||
<string name="pref_cache_weather_summary">As informações do clima serão armazenadas em cache durante as reinicializações do aplicativo.</string>
|
||||
<string name="dual_band">Dual Band</string>
|
||||
<string name="steps_streaks_since_date">Desde %s</string>
|
||||
<string name="step_streaks_achievements_sharing_message">Minhas conquistas diárias de passos!</string>
|
||||
<string name="watchface_resolution_doesnt_match">A resolução do watchface não corresponde à tela do dispositivo. Watchface é %1$s a tela do dispositivo é %2$s</string>
|
||||
<string name="pref_title_huawei_account">Conta da Huawei</string>
|
||||
<string name="appmanager_downloaded_to_cache">Download de %s para o cache</string>
|
||||
<string name="appmanager_download_app_error">Erro no download do aplicativo</string>
|
||||
<string name="open_fw_installer_connect_minimum_one_device">Conecte pelo menos um dispositivo para o qual você deseja enviar o arquivo.</string>
|
||||
<string name="pref_header_sound_vibration">Som e vibração</string>
|
||||
<string name="open_fw_installer_connect_maximum_one_device">Conecte APENAS UM dispositivo para o qual você deseja enviar o arquivo.</string>
|
||||
<string name="pref_header_offline_voice">Voz offline</string>
|
||||
<string name="open_fw_installer_ensure_device_connected">Certifique-se de que o dispositivo %s esteja conectado</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip3">Você está prestes a instalar o firmware %s no seu Amazfit Bip 3.
|
||||
\n
|
||||
\nCertifique-se de instalar o arquivo .fw, e depois o arquivo .res. Seu relógio será reiniciado após a instalação do arquivo .fw.
|
||||
\n
|
||||
\nNota: você não precisa instalar .res se esse arquivo for exatamente o mesmo que os instalados anteriormente.
|
||||
\n
|
||||
\nPROSSIGA POR SUA CONTA E RISCO!</string>
|
||||
<string name="fw_upgrade_notice_miband7">Você está prestes a instalar o firmware %s no seu Xiaomi Smart Band 7.
|
||||
\n
|
||||
\nCertifique-se de instalar o arquivo .fw, e depois o arquivo .res. Seu relógio será reiniciado após a instalação do arquivo .fw.
|
||||
\n
|
||||
\nPROSSIGA POR SUA CONTA E RISCO!</string>
|
||||
<string name="uploadwatchfaceoperation_complete">Instalação do Watchface concluída</string>
|
||||
<string name="uploadwatchfaceoperation_failed">Falha na instalação do Watchface</string>
|
||||
</resources>
|
|
@ -1118,7 +1118,7 @@
|
|||
<string name="movement_intensity">Интенсивность движения</string>
|
||||
<string name="devicestatus_upload_started">Загрузка началась</string>
|
||||
<string name="activity_list_summary_activities">Активности</string>
|
||||
<string name="menuitem_sleep">Шаги</string>
|
||||
<string name="menuitem_sleep">Сон</string>
|
||||
<string name="devicetype_amazfit_bipu">Amazfit Bip U</string>
|
||||
<string name="pref_title_upper_button_function_double">Двойное нажатие на верхнюю кнопку</string>
|
||||
<string name="pref_title_lower_button_function_double">Двойное нажатие на нижнюю кнопку</string>
|
||||
|
@ -1855,7 +1855,7 @@
|
|||
<string name="error_setting_parent_folder">Ошибка задания родительской папки: %s</string>
|
||||
<string name="autoconnect_from_device_summary">Подключаться в случае когда соединение инициировано устройством, например, наушниками</string>
|
||||
<string name="devicetype_sony_wh_1000xm2">Sony WH-1000XM2</string>
|
||||
<string name="info_no_devices_connected">нет подключенных устройств</string>
|
||||
<string name="info_no_devices_connected">Нет подключенных устройств</string>
|
||||
<string name="controlcenter_set_parent_folder">Задать родительскую папку</string>
|
||||
<string name="controlcenter_set_folder_title">Укажите папку или создайте новую</string>
|
||||
<string name="autoconnect_from_device_title">Подключаться при подключении с устройства</string>
|
||||
|
@ -2665,13 +2665,13 @@
|
|||
<string name="pref_heartrate_automatic_enable">Автоизмерение сердцебиения</string>
|
||||
<string name="pref_spo_automatic_enable">Автоизмерение кислорода в крови</string>
|
||||
<string name="pref_force_options">Форсирование опций</string>
|
||||
<string name="pref_force_smart_alarm">Форсировать умный будильник</string>
|
||||
<string name="pref_force_smart_alarm">Поддержка умного будильника</string>
|
||||
<string name="pref_force_smart_alarm_summary">Форсировать поддержку умных будильников.
|
||||
\nИСПОЛЬЗУЙТЕ НА СВОЙ РИСК</string>
|
||||
<string name="pref_force_wear_location">Форсировать место ношения</string>
|
||||
<string name="pref_force_wear_location">Поддержка места ношения</string>
|
||||
<string name="pref_force_wear_location_summary">Форсировать поддержку расположения ношения устройства.
|
||||
\nИСПОЛЬЗУЙТЕ НА СВОЙ РИСК</string>
|
||||
<string name="pref_force_dnd_support">Форсировать поддержку \"не беспокоить\"</string>
|
||||
<string name="pref_force_dnd_support">Поддержка \"не беспокоить\"</string>
|
||||
<string name="huawei_ignore_wakeup_status_start">Игнорировать статус начала вставания</string>
|
||||
<string name="huawei_ignore_wakeup_status_start_description">Может помочь исправить распознание сна. Сразу видимо в обзоре дневных активностей.</string>
|
||||
<string name="huawei_ignore_wakeup_status_end">Игнорировать статус окончания вставания</string>
|
||||
|
@ -2787,4 +2787,43 @@
|
|||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="busy_task_fetch_sports_details_interrupted">Получение подробностей о спорте было прервано</string>
|
||||
<string name="pref_force_enable_heartrate_support">Поддержка измерения пульса</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">Форсировать поддержку измерения уровня кислорода в крови.
|
||||
\nИСПОЛЬЗУЙТЕ НА СВОЙ РИСК</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">Форсировать поддержку измерения пульса.
|
||||
\nИСПОЛЬЗУЙТЕ НА СВОЙ РИСК</string>
|
||||
<string name="pref_force_enable_spo2_support">Поддержка измерения SpO2</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">Позволить виджету занять две колонки на обзорной панели</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">Показывать значения цветов под виджетом</string>
|
||||
<string name="pref_dashboard_select_devices_title">Выбрать устройства...</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">Выберите виджеты и порядок их отображения на главном экране</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">Показывать активность в одном 24-часовом кружке вместо двойного 12ч</string>
|
||||
<string name="pref_auto_reply_calls_title">Принимать звонки автоматически</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">Задержка перед автоприёмом</string>
|
||||
<string name="pref_auto_reply_calls_summary">Телефон будет автоматически принимать входящие звонки</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">Время в секундах до того, как звонок будет автоматически принят</string>
|
||||
<string name="pref_header_generic">Общий</string>
|
||||
<string name="pref_header_audio">Звук</string>
|
||||
<string name="activity_type_free_training">Свободная тренировка</string>
|
||||
<string name="activity_type_dynamic_cycle">Динамический цикл</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">Интервал измерений пульса</string>
|
||||
<string name="pref_speak_notifications_aloud_title">Произносить уведомления вслух</string>
|
||||
<string name="pref_header_calls_and_notifications">Вызовы и уведомления</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">Показывать обозначения</string>
|
||||
<string name="armenian">Армянский</string>
|
||||
<string name="devicetype_redmi_watch_4">Redmi Watch 4</string>
|
||||
<string name="pref_title_notification_wake_on_open">Автопробуждение и разблокировка</string>
|
||||
<string name="pref_summary_notification_wake_on_open">Пробуждать и разблокировать Android-устройство когда носимое устройство отвечает с OPEN. Нужно быть в доверенном состоянии.</string>
|
||||
<string name="pref_sleepasandroid_features_title">Функции</string>
|
||||
<string name="pref_sleepasandroid_features_summary">Поддержка варьируется в зависимости от устройства</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">Акселерометр</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">Пульс</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SpO2</string>
|
||||
<string name="pref_title_bottom_navigation_bar">Нижняя панель навигации</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_on">Переключаться между основными экранами через панель навигации или жестами</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">Уведомления</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_off">Переключаться между основными экранами только по жестам</string>
|
||||
<string name="serbian">Сербский</string>
|
||||
<string name="pref_title_huawei_account">Учётная запись Huawei</string>
|
||||
<string name="pref_summary_huawei_account">Используется для сопряжения без сброса устройства.</string>
|
||||
</resources>
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="about_activity_title_generic">เกี่ยวกับ Gadgetbridge</string>
|
||||
<string name="application_name_generic"></string>
|
||||
<string name="application_name_generic">Gadgetbridge</string>
|
||||
<string name="gadgetbridge_running_generic">Gadgetbridge กำลังทำงาน</string>
|
||||
<string name="about_description_generic">แอปเสรีไม่สงวนลิขสิทธิ์ ไม่พึ่งระบบคลาวด์ สำหรับใช้ทดแทนแอปจากผู้ผลิตที่ไม่เปิดเผยโค้ดอิสระ</string>
|
||||
<string name="title_activity_controlcenter_generic"></string>
|
||||
<string name="title_activity_controlcenter_generic">Gadgetbridge</string>
|
||||
<string name="about_activity_title_banglejs_main">เกี่ยวกับ Bangle.js Gadgetbridge</string>
|
||||
<string name="gadgetbridge_running_banglejs_main">Bangle.js กำลังทำงานอยู่</string>
|
||||
<string name="application_name_banglejs_nightly"></string>
|
||||
<string name="title_activity_controlcenter_banglejs_nightly"></string>
|
||||
<string name="application_name_banglejs_nightly">Bangle.js Gadgetbridge (Nightly)</string>
|
||||
<string name="title_activity_controlcenter_banglejs_nightly">Bangle.js Gadgetbridge (Nightly)</string>
|
||||
<string name="gadgetbridge_running_banglejs_nightly">Nightly Bangle.js กำลังทำงานอยู่</string>
|
||||
<string name="about_activity_title_main_nightly">เกี่ยวกับ Gadgetbridge Nightly</string>
|
||||
<string name="title_activity_controlcenter_main_nightly"></string>
|
||||
<string name="about_activity_title_main_nightly">เกี่ยวกับ Gadgetbridge รุ่นทดสอบ</string>
|
||||
<string name="title_activity_controlcenter_main_nightly">Gadgetbridge Nightly</string>
|
||||
<string name="gadgetbridge_running_main_nightly">Nightly GB กำลังทำงานอยู่</string>
|
||||
<string name="application_name_main_nopebble">Gadgetbridge (Nightly โดยไม่มี Pebble provider)</string>
|
||||
<string name="title_activity_controlcenter_main_nopebble">Gadgetbridge Nightly แบบไม่มี Pebbleล</string>
|
||||
<string name="about_activity_title_main_nopebble">เกี่ยวกับ Gadgetbridge Nightly แบบไม่มี Pebbleล</string>
|
||||
<string name="about_activity_title_main_nopebble">About Gadgetbridge Nightly No Pebble</string>
|
||||
<string name="action_settings">การตั้งค่า</string>
|
||||
<string name="action_debug">ดีบั้ก</string>
|
||||
<string name="action_quit">ออก</string>
|
||||
|
@ -67,8 +67,8 @@
|
|||
<string name="title_activity_debug">ดีบั้ก</string>
|
||||
<string name="debugactivity_really_factoryreset_title">คืนค่าเรื่มต้นจากโรงงาน?</string>
|
||||
<string name="debugactivity_confirm_remove_device_preferences_title">ลบการตั้งค่าของอุปกรณ์?</string>
|
||||
<string name="about_activity_title_banglejs_nightly">เกี่ยวกับ Bangle.js Gadgetbridge (Nightly)</string>
|
||||
<string name="about_description_main_nightly">แอปเสรีไม่สงวนลิขสิทธิ์ ไม่พึ่งระบบคลาวด์ สำหรับใช้ทดแทนแอปแก็ดเจ็ตต่างๆจากผู้ผลิตที่ไม่เปิดเผยโค้ดอิสระ เวอร์ชั่น Nightly ของ Gadgetbridge ไม่สามารถติดตั้งซ้อนได้หากคุณมีแอป Gadgetbridge หรือ Pebble ติดตั้งอยู่แล้ว เนื่องจากการขัดแย้งกันของ Pebble provider</string>
|
||||
<string name="about_activity_title_banglejs_nightly">เกี่ยวกับ Bangle.js Gadgetbridge (รุ่นทดสอบ)</string>
|
||||
<string name="about_description_main_nightly">แอปเสรีไม่สงวนลิขสิทธิ์ ไม่พึ่งระบบคลาวด์ สำหรับใช้ทดแทนแอปแก็ดเจ็ตต่างๆจากผู้ผลิตที่ไม่เปิดเผยโค้ดอิสระ เวอร์ชั่นทดสอบของ Gadgetbridge ไม่สามารถติดตั้งคู่กันได้หากคุณมีแอป Gadgetbridge หรือ Pebble ติดตั้งอยู่แล้ว เนื่องจากการขัดแย้งกันของ Pebble provider</string>
|
||||
<string name="controlcenter_delete_device">ลบอุปกรณ์</string>
|
||||
<string name="prefs_activity_in_device_card_title">แสดงข้อมูลกิจกรรมบนการ์ดของอุปกรณ์</string>
|
||||
<string name="prefs_activity_in_device_card_title_summary">แสดงจำนวนก้าวเดินปัจจุบัน ระยะทางหรือการนอนหลับบนการ์ดของอุปกรณ์</string>
|
||||
|
@ -81,4 +81,40 @@
|
|||
\n
|
||||
\nเนื่องจากนโยบายของ Google Play เราจึงไม่สามารถเพื่มช่องการบริจาคในแอปได้โดยตรง แต่ถ้าคุณชอบแอปนี้โปรดพิจารณาบริจาคผ่านหน้าหลักของ Gadgetbridge ด้านล่างนี้</string>
|
||||
<string name="debugactivity_really_factoryreset">การคืนค่าโรงงานจะลบข้อมูลทุกอย่างของอุปกรณ์ Xiaomi/Huami (ที่รองรับ) และยังเปลี่ยนที่อยู่ Bluetooth MAC address ฉะนั้น Gadgetbridge จะมองเห็นเป็นอุปกรณ์ใหม่</string>
|
||||
<string name="application_name_banglejs_main">Bangle.js Gadgetbridge</string>
|
||||
<string name="title_activity_controlcenter_banglejs_main">Bangle.js Gadgetbridge</string>
|
||||
<string name="application_name_main_nightly">Gadgetbridge (รุ่นทดสอบ)</string>
|
||||
<string name="about_links">ลิงก์</string>
|
||||
<string name="single_band">ช่องความถี่เดี่ยว</string>
|
||||
<string name="dual_band">ช่องความถี่คู่</string>
|
||||
<string name="debugactivity_confirm_remove_device_preferences">นี่จะเป็นการรีเซ็ตการตั้งค่าของทุกอุปกรณ์ที่เชื่อมต่ออยู่ แน่ใจหรือ?</string>
|
||||
<string name="about_description_main_nopebble">แอปเสรีไม่สงวนลิขสิทธิ์ ไม่พึ่งระบบคลาวด์ สำหรับใช้ทดแทนแอปแก็ดเจ็ตต่างๆจากผู้ผลิตที่ไม่เปิดเผยโค้ดอิสระ เวอร์ชั่นทดสอบของ Gadgetbridge มี Pebble provider ที่ถูกเปลี่ยนชื่อเพื่อป้องกันการขัดแย้งกัน ฉะนั้นการทำงานร่วมกับฟีเจอร์บางอย่างของ Pebble อาจใช้ไม่ได้ แต่สามารถติดตั้งแอปนี้คู่กับแอป Gadgetbridge ที่มีอยู่แล้วได้</string>
|
||||
<string name="appmanager_installed_watchapps">แอปที่ติดตั้งแล้ว</string>
|
||||
<string name="appmanager_installed_watchfaces">หน้าปัดนาฬิกาที่ติดตั้งแล้ว</string>
|
||||
<string name="about_core_team_title">ผู้ร่วมพัฒนาหลักๆ(ตั้งแต่เรื่มพัฒนาแรกๆ)</string>
|
||||
<string name="gadgetbridge_running_main_nopebble">Nightly NoPebble GB กำลังทำงาน</string>
|
||||
<string name="appmanager_app_share">แชร์</string>
|
||||
<string name="title_activity_notification_management">การตั้งค่าการแจ้งเตือน</string>
|
||||
<string name="pref_title_notifications_call">เมื่อมีสายเข้า</string>
|
||||
<string name="pref_title_notifications_ignore_low_priority">ไม่สนใจการแจ้งเตือนความสำคัญต่ำ</string>
|
||||
<string name="pref_title_notifications_generic_settings">การตั้งค่าการแจ้งเตือนของ Android</string>
|
||||
<string name="pref_title_notifications_generic">การรองรับการแจ้งเตือนทั่วไป</string>
|
||||
<string name="pref_title_whenscreenon">...และเมื่อหน้าจอเปิดอยู่</string>
|
||||
<string name="pref_summary_notifications_ignore_low_priority">ไม่ต้องส่งการแจ้งเตือนที่มีความสำคัญต่ำต่างๆไปยังอุปกรณ์</string>
|
||||
<string name="pref_title_support_voip_calls">การโทรจากระบบ VoIP</string>
|
||||
<string name="pref_summary_notification_prefer_long_text">หากเป็นไปได้ ให้ส่งการแจ้งเตือนที่มีข้อความยาวๆ ไปยังอุปกรณ์</string>
|
||||
<string name="pref_summary_notifications_ignore_work_profile">ไม่ต้องส่งการแจ้งเตือนจากแอปที่อยู่ในโปรไฟล์งานไปยังอุปกรณ์</string>
|
||||
<string name="pref_title_notification_cache_while_disconnected">แคชการแจังเตือนไว้</string>
|
||||
<string name="pref_summary_notification_cache_while_disconnected">ส่งการแจ้งเตือนที่พลาดไป เมื่ออุปกรณ์กลับมาเชื่อมต่ออีกครั้งหลังจากไม่อยู่ในระยะการเชื่อมต่อ</string>
|
||||
<string name="pref_title_notification_prefer_long_text">ส่งการแจ้งเตือนข้อความยาวๆ</string>
|
||||
<string name="never">ไม่เลย</string>
|
||||
<string name="always">ตลอดเวลา</string>
|
||||
<string name="pref_title_notifications_ignore_work_profile">ไม่สนใจการแจ้งเตือนจากโปรไฟล์งาน</string>
|
||||
<string name="pref_title_ping_tone">เสียงตอนปิงอุปกรณ์</string>
|
||||
<string name="pref_title_notification_delay_calls">หน่วงการแจ้งเตือนการโทร</string>
|
||||
<string name="pref_summary_notification_delay_calls">หน่วงไว้ก่อนจะส่งการไปแจ้งเตือนไปยังอุปกรณ์ หน่วยเป็นวินาที</string>
|
||||
<string name="about_contributors">ผู้ร่วมพัฒนา</string>
|
||||
<string name="about_additional_device_support">ผู้สนับสนุนการรองรับอุปกรณ์เพื่มเติม</string>
|
||||
<string name="about_additional_contributions">ขอขอบคุณผู่ร่วมพัฒนาทุกท่านที่ช่วยกันแก้ไขโค้ด, แปลภาษา, ช่วยเหลือ, ออกไอเดีย, ให้กำลังใจ, แจ้งบั้ก, และบริจาคเงิน... ✊</string>
|
||||
<string name="action_discover">เชื่อมต่ออุปกรณ์ใหม่</string>
|
||||
</resources>
|
|
@ -1734,7 +1734,7 @@
|
|||
<string name="permission_location">%1$s ekranınız kapalıyken bile saatinize bağlı kalmasını sağlamak için arka planda konumunuza erişmeye ihtiyaç duyuyor.
|
||||
\n
|
||||
\nKabul etmek için lütfen \'%2$s\' düğmesine dokunun.</string>
|
||||
<string name="info_no_devices_connected">bağlı aygıt yok</string>
|
||||
<string name="info_no_devices_connected">Bağlı aygıt yok</string>
|
||||
<string name="info_connected_count">%d aygıt bağlı</string>
|
||||
<string name="estonian">Estonca</string>
|
||||
<string name="lithuanian">Litvanyaca</string>
|
||||
|
@ -2854,4 +2854,122 @@
|
|||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="busy_task_fetch_sports_details_interrupted">Spor bilgilerinin getirilmesi yarıda kesildi</string>
|
||||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="companion_pairing_request_title">Yardımcı aygıt</string>
|
||||
<string name="companion_pairing_request_description">Bu aygıt yardımcı olarak eşleştirilsin mi?
|
||||
\n
|
||||
\nBu, aygıt bulma gibi bazı işlevler için tavsiye edilir ve daha iyi bir bağlantı sağlar.</string>
|
||||
<string name="unbind_before_pair_title">Zaten bağlı</string>
|
||||
<string name="unbind_before_pair_message">Bu aygıt Android ayarlarında zaten bağlı, bu da bazı aygıtlar için eşleştirmenin başarısız olmasına neden olabilir.
|
||||
\n
|
||||
\nAygıtı eklemek başarısız olursa, lütfen Android ayarlarından kaldırın ve tekrar deneyin.</string>
|
||||
<string name="devicesetting_scannable_debounce">Taranabilir hata giderme zaman aşımı (saniye)</string>
|
||||
<string name="devicesetting_scannable_rssi">En düşük RSSI eşiği</string>
|
||||
<string name="devicesetting_scannable_debounce_summary">Tarandıktan sonra aygıt tarandı olarak kalır ve belirtilen süre boyunca yok sayılır</string>
|
||||
<string name="devicetype_scannable">Taranabilir aygıt</string>
|
||||
<string name="state_scanned">Tarandı</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">En kısa görülmeme süresi (saniye)</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">Tarandıktan sonra, aygıtın tekrar kaydedilmeden önce bu süre boyunca görülmemesi gerekir</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">Algılama için en düşük RSSI eşiği</string>
|
||||
<string name="swolfAvg">Ortalama swolf</string>
|
||||
<string name="swolfMax">En yüksek swolf</string>
|
||||
<string name="swolfMin">En düşük swolf</string>
|
||||
<string name="stepRateSum">Adım hızı toplamı</string>
|
||||
<string name="stepRateAvg">Ortalama adım hızı</string>
|
||||
<string name="stepLengthAvg">Ortalama Adım Uzunluğu</string>
|
||||
<string name="groundContactTimeAvg">Ortalama yerle temas süresi</string>
|
||||
<string name="impactAvg">Ortalama etki</string>
|
||||
<string name="impactMax">En yüksek etki</string>
|
||||
<string name="swingAngleAvg">Ortalama salınım açısı</string>
|
||||
<string name="foreFootLandings">Ön ayak inişi</string>
|
||||
<string name="midFootLandings">Orta ayak inişi</string>
|
||||
<string name="backFootLandings">Arka ayak inişi</string>
|
||||
<string name="eversionAngleAvg">Ortalama ters dönme açısı</string>
|
||||
<string name="eversionAngleMax">En yüksek ters dönme açısı</string>
|
||||
<string name="fmtPaceDistance">Hız %d mesafe</string>
|
||||
<string name="fmtPaceType">Hız %d tür</string>
|
||||
<string name="fmtPacePace">Hız %d hız</string>
|
||||
<string name="fmtPaceCorrection">Hız %d düzeltme</string>
|
||||
<string name="fmtPaceTypeAverage">Hız Türü %d ortalama</string>
|
||||
<string name="unknownDataEncountered">Bilinmeyen veriyle karşılaşıldı</string>
|
||||
<string name="milliseconds">milisaniye</string>
|
||||
<string name="degrees">derece</string>
|
||||
<string name="Pace">Hız</string>
|
||||
<string name="RunningForm">Koşu Biçimi</string>
|
||||
<string name="pref_force_enable_heartrate_support">Kalp ritmi desteğini zorla</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">Kalp ritmi desteğini etkinleştirmeye zorla.
|
||||
\nKULLANMANIZ DURUMUNDA RİSK SİZE AİTTİR</string>
|
||||
<string name="pref_force_enable_spo2_support">SpO2 desteğini zorla</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">SpO2 desteğini etkinleştirmeye zorla.
|
||||
\nKULLANMANIZ DURUMUNDA RİSK SİZE AİTTİR</string>
|
||||
<string name="activity_type_worn">Yorgun</string>
|
||||
<string name="pref_dashboard_cards_title">Kartlarda widget\'ları göster</string>
|
||||
<string name="error_showing_changelog">Değişiklik günlüğü gösterilirken hata oluştu</string>
|
||||
<string name="dashboard_settings">Gösterge tablosu ayarları</string>
|
||||
<string name="pref_dashboard_cards_summary">Gösterge tablosunda widget\'ların etrafına kartlar çiz</string>
|
||||
<string name="pref_dashboard_first_title">Önce gösterge tablosunu göster</string>
|
||||
<string name="pref_dashboard_first_summary">Gadgetbridge başladığında aygıtlar ekranı yerine gösterge tablosunu göster</string>
|
||||
<string name="pref_dashboard_widget_settings">Widget ayarları</string>
|
||||
<string name="pref_dashboard_widget_today_title">Etkinlik çizelgesi</string>
|
||||
<string name="pref_dashboard_all_devices_title">Tüm aygıtlar</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">Kalp ritmi aralığı</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">Widget\'ın gösterge tablosunda iki sütun kaplamasına izin ver</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">Widget\'ın altında renkleri açıklayan bir açıklama göster</string>
|
||||
<string name="pref_dashboard_all_devices_summary">Gösterge tablosundaki toplamlar için eklenen tüm aygıtlardan gelen etkinlik verilerini birleştir</string>
|
||||
<string name="bottom_nav_dashboard">Gösterge tablosu</string>
|
||||
<string name="bottom_nav_devices">Aygıtlar</string>
|
||||
<string name="pref_dashboard_widget_today_24h_title">24 saat modu</string>
|
||||
<string name="pref_dashboard_widget_double_size_title">İki katı boyut</string>
|
||||
<string name="pref_dashboard_widget_goals_chart_title">Hedefler çizelgesi</string>
|
||||
<string name="pref_dashboard_devices_to_include">Dahil edilecek aygıtlar</string>
|
||||
<string name="pref_dashboard_select_devices_title">Aygıtları seç...</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">Hangi widget\'ların etkinleştirileceğini ve gösterge tablosunda hangi sırada görüntüleneceğini seçin</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">Etkinliği iki tane 12 saatlik daire yerine bir tane 24 saatlik daire içinde göster</string>
|
||||
<string name="pref_dashboard_select_devices_summary">Gösterge tablosundaki toplamlar için belirli aygıtlardan gelen etkinlik verilerini birleştir</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_summary">Her başarılı kalp ritmi ölçümünden sonra grafiğin \'yorgun\' olarak gösterdiği dakika miktarı</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">Açıklamaları göster</string>
|
||||
<string name="pref_auto_reply_calls_summary">Telefon gelen aramaları otomatik olarak yanıtlayacaktır</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">Aramanın otomatik olarak yanıtlanacağı saniye sayısı</string>
|
||||
<string name="pref_auto_reply_calls_title">Telefon aramalarını otomatik yanıtla</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">Otomatik Yanıt Gecikmesi</string>
|
||||
<string name="pref_header_audio">Ses</string>
|
||||
<string name="pref_header_generic">Genel</string>
|
||||
<string name="pref_title_notification_wake_on_open">Otomatik uyandır ve kilidi aç</string>
|
||||
<string name="pref_summary_notification_wake_on_open">Aygıt bir OPEN (AÇ) yanıtı gönderdiğinde Android aygıtını uyandırın ve kilidini açın. Güvenilir bir durumda olması gerekir.</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">Bildirimler kulaklıklardan yüksek sesle okunacaktır</string>
|
||||
<string name="pref_speak_notifications_aloud_title">Bildirimleri Sesli Oku</string>
|
||||
<string name="devicetype_redmi_watch_4">Redmi Watch 4</string>
|
||||
<string name="widget_layout_top_wide_bot_large">Yukarıda geniş, aşağıda büyük</string>
|
||||
<string name="widget_layout_top_large_bot_wide">Yukarıda büyük, aşağıda geniş</string>
|
||||
<string name="widget_name_colored_tile">%1$s (renkli döşeme)</string>
|
||||
<string name="widget_name_untitled">Başlıksız widget (%1$s)</string>
|
||||
<string name="pref_header_calls_and_notifications">Çağrılar ve bildirimler</string>
|
||||
<string name="armenian">Ermenice</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_off">Yalnızca yatay kaydırma kullanarak ana ekranlar arasında geçiş yapın</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_on">Gezinme çubuğunu veya yatay kaydırmayı kullanarak ana ekranlar arasında geçiş yapın</string>
|
||||
<string name="pref_title_bottom_navigation_bar">Alt gezinme çubuğu</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_title">Gece yarısı altta</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_summary">24 saat modunda, gece yarısını grafiğin alt kısmına, gün ortasını ise grafiğin üst kısmına çiz</string>
|
||||
<string name="pref_sleepasandroid_features_summary">Destek aygıttan aygıta farklılık gösterir</string>
|
||||
<string name="pref_sleepasandroid_feat_alarms">Alarmlar</string>
|
||||
<string name="pref_sleepasandroid_slot_title">Alarm yuvası</string>
|
||||
<string name="alarm_slot_reset">Alarm yuvası öntanımlı olarak ayarlandı</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">Kalp ritmi</string>
|
||||
<string name="pref_sleepasandroid_feat_oximetry">Oksimetri</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SPO2</string>
|
||||
<string name="sleepasandroid_settings">Sleep As Android</string>
|
||||
<string name="pref_sleepasandroid_slot_summary">Alarmları ayarlarken hangi alarm yuvasının kullanılacağı</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">Bildirimler</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">İvmeölçer</string>
|
||||
<string name="pref_sleepasandroid_enable_summary">Sleep As Android bütünleşmesini etkinleştir</string>
|
||||
<string name="pref_sleepasandroid_device_title">Sağlayıcı aygıt</string>
|
||||
<string name="pref_sleepasandroid_device_summary">Sleep As Android veri sağlayıcısı olarak aygıtı seçin</string>
|
||||
<string name="pref_sleepasandroid_features_title">Özellikler</string>
|
||||
<string name="pref_summary_huawei_account">Eşleştirme işleminde kullanılan Huawei hesabı. Ayarlanması, fabrika ayarlarına sıfırlamadan eşleştirmeyi sağlar.</string>
|
||||
<string name="pref_title_huawei_account">Huawei Hesabı</string>
|
||||
<string name="serbian">Sırpça</string>
|
||||
<string name="watchface_resolution_doesnt_match">Saat arayüzü çözünürlüğü aygıt ekranıyla eşleşmiyor. Saat arayüzü %1$s, aygıt ekranı %2$s</string>
|
||||
<string name="cyclingPowerMin">En düşük bisiklet gücü</string>
|
||||
<string name="cyclingPowerAverage">Ortalama bisiklet gücü</string>
|
||||
<string name="cyclingPowerMax">En yüksek bisiklet gücü</string>
|
||||
<string name="devicetype_huawei_watchfit2">Huawei Watch Fit 2</string>
|
||||
</resources>
|
|
@ -553,7 +553,7 @@
|
|||
<string name="activity_type_activity">活动</string>
|
||||
<string name="activity_type_light_sleep">浅睡眠</string>
|
||||
<string name="activity_type_deep_sleep">深睡眠</string>
|
||||
<string name="activity_type_not_worn">设备没有磨损</string>
|
||||
<string name="activity_type_not_worn">设备没有佩戴</string>
|
||||
<string name="activity_type_running">跑步</string>
|
||||
<string name="activity_type_walking">走路</string>
|
||||
<string name="activity_type_swimming">游泳</string>
|
||||
|
@ -2842,4 +2842,122 @@
|
|||
<string name="devicetype_huawei_watchgt4">华为手表 GT 4</string>
|
||||
<string name="busy_task_fetch_sports_details_interrupted">获取运动详情时被中断</string>
|
||||
<string name="devicetype_huawei_watchultimate">华为手表 Ultimate</string>
|
||||
<string name="unbind_before_pair_title">已绑定</string>
|
||||
<string name="companion_pairing_request_title">陪伴设备</string>
|
||||
<string name="companion_pairing_request_description">将此设备配对为陪伴设备?
|
||||
\n
|
||||
\n建议将此功能用于某些功能(例如查找设备),并提供更好的连接。</string>
|
||||
<string name="unbind_before_pair_message">该设备已在 Android 设置中绑定,这可能会导致某些设备配对失败。
|
||||
\n
|
||||
\n如果添加设备失败,请在 Android 设置中将其删除,然后重试。</string>
|
||||
<string name="devicetype_scannable">可扫描的设备</string>
|
||||
<string name="state_scanned">已扫描</string>
|
||||
<string name="devicesetting_scannable_rssi">最小 RSSI 阈值</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">检测的最小 RSSI 阈值</string>
|
||||
<string name="devicesetting_scannable_debounce">可扫描的去抖动超时(秒)</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">最短未发现时间(秒)</string>
|
||||
<string name="devicesetting_scannable_debounce_summary">扫描后,设备将保持扫描状态并在指定时间内被忽略</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">扫描后,设备必须在这段时间内不可见,然后才能再次注册</string>
|
||||
<string name="swolfAvg">平均 Swolf</string>
|
||||
<string name="swolfMax">最大 Swolf</string>
|
||||
<string name="swolfMin">最小 Swolf</string>
|
||||
<string name="stepRateSum">步速总和</string>
|
||||
<string name="stepRateAvg">平均步速</string>
|
||||
<string name="stepLengthAvg">平均步长</string>
|
||||
<string name="groundContactTimeAvg">平均触地时间</string>
|
||||
<string name="impactAvg">平均影响</string>
|
||||
<string name="impactMax">最大影响</string>
|
||||
<string name="swingAngleAvg">平均摆角</string>
|
||||
<string name="foreFootLandings">前脚落地</string>
|
||||
<string name="midFootLandings">中足落地</string>
|
||||
<string name="backFootLandings">后脚落地</string>
|
||||
<string name="eversionAngleAvg">平均外翻角度</string>
|
||||
<string name="eversionAngleMax">最大外翻角度</string>
|
||||
<string name="fmtPaceDistance">步速 %d 距离</string>
|
||||
<string name="fmtPaceType">步速 %d 类型</string>
|
||||
<string name="fmtPacePace">步速 %d 步速</string>
|
||||
<string name="degrees">度</string>
|
||||
<string name="fmtPaceCorrection">步速 %d 修正</string>
|
||||
<string name="fmtPaceTypeAverage">配速类型 %d 平均值</string>
|
||||
<string name="unknownDataEncountered">遇到未知数据</string>
|
||||
<string name="milliseconds">毫秒</string>
|
||||
<string name="Pace">步伐</string>
|
||||
<string name="RunningForm">跑步形式</string>
|
||||
<string name="pref_force_enable_heartrate_support">强制支持心率</string>
|
||||
<string name="pref_force_enable_spo2_support">强制支持血氧</string>
|
||||
<string name="pref_force_enable_heartrate_support_summary">强制启用心率支持。
|
||||
\n风险自担</string>
|
||||
<string name="pref_force_enable_spo2_support_summary">强制启用血氧支持。
|
||||
\n风险自担</string>
|
||||
<string name="pref_dashboard_devices_to_include">要包括的设备</string>
|
||||
<string name="pref_dashboard_all_devices_title">所有设备</string>
|
||||
<string name="pref_dashboard_select_devices_title">选择设备...</string>
|
||||
<string name="pref_dashboard_widgets_order_summary">选择启用哪些小部件以及它们在仪表板上的显示顺序</string>
|
||||
<string name="pref_dashboard_widget_today_24h_summary">以单个 24 小时圆圈而不是双 12 小时圆圈显示活动</string>
|
||||
<string name="pref_dashboard_widget_show_legend_summary">在小部件下方显示说明颜色的图例</string>
|
||||
<string name="pref_dashboard_select_devices_summary">将来自特定设备的活动数据合并到仪表板上的总计中</string>
|
||||
<string name="activity_type_worn">佩戴</string>
|
||||
<string name="bottom_nav_dashboard">仪表板</string>
|
||||
<string name="error_showing_changelog">显示变更日志时出错</string>
|
||||
<string name="dashboard_settings">仪表板设置</string>
|
||||
<string name="bottom_nav_devices">设备</string>
|
||||
<string name="pref_dashboard_first_title">首先显示仪表板</string>
|
||||
<string name="pref_dashboard_first_summary">Gadgetbridge 启动时显示仪表板,而不是设备屏幕</string>
|
||||
<string name="pref_dashboard_cards_title">在卡片上显示小部件</string>
|
||||
<string name="pref_dashboard_cards_summary">在仪表板上的小部件周围绘制卡片</string>
|
||||
<string name="pref_dashboard_widget_settings">小部件设置</string>
|
||||
<string name="pref_dashboard_widget_today_title">活动图表</string>
|
||||
<string name="pref_dashboard_widget_today_24h_title">24小时模式</string>
|
||||
<string name="pref_dashboard_widget_double_size_title">双倍尺寸</string>
|
||||
<string name="pref_dashboard_widget_goals_chart_title">目标图表</string>
|
||||
<string name="pref_dashboard_widget_show_legend_title">显示图例</string>
|
||||
<string name="pref_dashboard_widget_double_size_summary">允许小部件占据仪表板上的两列</string>
|
||||
<string name="pref_dashboard_all_devices_summary">将所有添加设备的活动数据合并到仪表板上的总计中</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_title">心率区间</string>
|
||||
<string name="pref_dashboard_widget_today_hr_interval_summary">每次成功测量心率后图表显示“佩戴”的分钟数</string>
|
||||
<string name="pref_auto_reply_calls_summary">手机将自动接听来电</string>
|
||||
<string name="pref_auto_reply_calls_title">自动接听电话</string>
|
||||
<string name="pref_auto_reply_calls_delay_summary">自动接听电话之前的秒数</string>
|
||||
<string name="pref_auto_reply_calls_delay_title">自动应答延迟</string>
|
||||
<string name="pref_header_audio">音频</string>
|
||||
<string name="pref_header_generic">普通</string>
|
||||
<string name="pref_title_notification_wake_on_open">自动唤醒并解锁</string>
|
||||
<string name="pref_summary_notification_wake_on_open">当小工具发回 OPEN 响应时,唤醒并解锁 Android 设备。需要处于可信状态。</string>
|
||||
<string name="widget_layout_top_wide_bot_large">上面宽,下面大</string>
|
||||
<string name="widget_layout_top_large_bot_wide">上面大,下面宽</string>
|
||||
<string name="widget_name_colored_tile">%1$s (彩色磁贴)</string>
|
||||
<string name="devicetype_redmi_watch_4">红米手表 4</string>
|
||||
<string name="pref_speak_notifications_aloud_summary">通知将通过耳机大声朗读</string>
|
||||
<string name="pref_speak_notifications_aloud_title">大声说出通知</string>
|
||||
<string name="widget_name_untitled">无标题小部件(%1$s)</string>
|
||||
<string name="pref_header_calls_and_notifications">来电和通知</string>
|
||||
<string name="armenian">亚美尼亚语</string>
|
||||
<string name="pref_title_bottom_navigation_bar">底部导航栏</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_off">仅使用水平滑动在主屏幕之间切换</string>
|
||||
<string name="pref_summary_bottom_navigation_bar_on">使用导航栏或横向滑动在主屏幕之间切换</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_summary">在 24 小时模式下,在图表底部绘制午夜,在图表顶部绘制中午</string>
|
||||
<string name="pref_dashboard_widget_today_upside_down_title">午夜在底部</string>
|
||||
<string name="pref_sleepasandroid_device_summary">选择 Sleep As Android 作为设备数据提供者</string>
|
||||
<string name="pref_sleepasandroid_device_title">设备提供者</string>
|
||||
<string name="pref_sleepasandroid_features_title">特点</string>
|
||||
<string name="pref_sleepasandroid_features_summary">支持因设备而异</string>
|
||||
<string name="pref_sleepasandroid_feat_movement">加速计</string>
|
||||
<string name="pref_sleepasandroid_feat_heartrate">心率</string>
|
||||
<string name="pref_sleepasandroid_feat_oximetry">血氧饱和度</string>
|
||||
<string name="pref_sleepasandroid_feat_spo2">SPO2</string>
|
||||
<string name="pref_sleepasandroid_feat_alarms">闹钟</string>
|
||||
<string name="pref_sleepasandroid_slot_summary">设置闹钟时使用哪个闹钟槽</string>
|
||||
<string name="pref_sleepasandroid_slot_title">闹钟槽</string>
|
||||
<string name="alarm_slot_reset">闹钟槽已设置为默认值</string>
|
||||
<string name="pref_sleepasandroid_feat_notifications">通知</string>
|
||||
<string name="sleepasandroid_settings">Sleep As Android</string>
|
||||
<string name="pref_summary_huawei_account">配对过程中使用的华为帐号。 设置它以允许在不恢复出厂设置的情况下进行配对。</string>
|
||||
<string name="pref_title_huawei_account">华为账号</string>
|
||||
<string name="serbian">塞尔维亚语</string>
|
||||
<string name="pref_sleepasandroid_enable_summary">启用 Sleep As Android 集成</string>
|
||||
<string name="watchface_resolution_doesnt_match">表盘分辨率与设备屏幕不匹配。表盘为 %1$s 设备屏幕为 %2$s</string>
|
||||
<string name="cyclingPowerMin">最小骑行功率</string>
|
||||
<string name="cyclingPowerAverage">平均骑行功率</string>
|
||||
<string name="cyclingPowerMax">最大骑行功率</string>
|
||||
<string name="devicetype_huawei_watchfit2">华为 Watch Fit 2</string>
|
||||
</resources>
|
|
@ -3441,6 +3441,27 @@
|
|||
<item>as_off</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="soundcore_button_function_names">
|
||||
<item>@string/pref_media_volumedown</item>
|
||||
<item>@string/pref_media_volumeup</item>
|
||||
<item>@string/pref_media_next</item>
|
||||
<item>@string/pref_media_previous</item>
|
||||
<item>@string/pref_media_playpause</item>
|
||||
<item>@string/pref_title_touch_voice_assistant</item>
|
||||
<item>@string/sony_button_mode_ambient_sound_control</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="soundcore_button_function_values">
|
||||
<item>VOLUME_DOWN</item>
|
||||
<item>VOLUME_UP</item>
|
||||
<item>MEDIA_NEXT</item>
|
||||
<item>MEDIA_PREV</item>
|
||||
<item>PLAYPAUSE</item>
|
||||
<item>VOICE_ASSISTANT</item>
|
||||
<item>AMBIENT_SOUND_CONTROL</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
<string-array name="fitness_tracking_apps_package_names">
|
||||
<item>de.dennisguse.opentracks</item>
|
||||
<item>de.dennisguse.opentracks.playStore</item>
|
||||
|
|
|
@ -520,6 +520,10 @@
|
|||
<string name="pref_gps_satellite_search">Satellite Search</string>
|
||||
<string name="pref_crown_vibration">Crown Vibration</string>
|
||||
<string name="pref_alert_tone">Alert Tone</string>
|
||||
<string name="pref_touch_tone">Touch Tone</string>
|
||||
<string name="pref_touch_tone_summary">Plays a tone when the earbud is touched</string>
|
||||
<string name="pref_wearing_tone">Wearing Tone</string>
|
||||
<string name="pref_wearing_tone_summary">Plays a tone when the earbud is inserted</string>
|
||||
<string name="pref_cover_to_mute">Cover to Mute</string>
|
||||
<string name="pref_vibrate_for_alert">Vibrate for Alert</string>
|
||||
<string name="pref_text_to_speech">Text to Speech</string>
|
||||
|
@ -1533,6 +1537,7 @@
|
|||
<string name="devicetype_sony_wi_sp600n">Sony WI-SP600N</string>
|
||||
<string name="devicetype_sony_linkbuds">Sony LinkBuds</string>
|
||||
<string name="devicetype_sony_linkbuds_s">Sony LinkBuds S</string>
|
||||
<string name="devicetype_soundcore_liberty3_pro">Soundcore Liberty 3 Pro</string>
|
||||
<string name="devicetype_binary_sensor">Binary sensor</string>
|
||||
<string name="devicetype_honor_band3">Honor Band 3</string>
|
||||
<string name="devicetype_honor_band4">Honor Band 4</string>
|
||||
|
@ -1552,6 +1557,7 @@
|
|||
<string name="devicetype_huawei_watchgt3">Huawei Watch GT 3 (Pro)</string>
|
||||
<string name="devicetype_huawei_watchgt4">Huawei Watch GT 4</string>
|
||||
<string name="devicetype_huawei_watchfit">Huawei Watch Fit</string>
|
||||
<string name="devicetype_huawei_watchfit2">Huawei Watch Fit 2</string>
|
||||
<string name="devicetype_huawei_watchultimate">Huawei Watch Ultimate</string>
|
||||
<string name="devicetype_femometer_vinca2">Femometer Vinca II</string>
|
||||
<string name="devicetype_xiaomi_watch_lite">Xiaomi Watch Lite</string>
|
||||
|
@ -1907,6 +1913,9 @@
|
|||
<string name="fmtPaceCorrection">Pace %d correction</string>
|
||||
<string name="fmtPaceTypeAverage">Pace Type %d average</string>
|
||||
<string name="unknownDataEncountered">Unknown data encountered</string>
|
||||
<string name="cyclingPowerAverage">Average cycling power</string>
|
||||
<string name="cyclingPowerMin">Min cycling power</string>
|
||||
<string name="cyclingPowerMax">Max cycling power</string>
|
||||
<!-- activity summary units-->
|
||||
<string name="meters">m</string>
|
||||
<string name="cm">cm</string>
|
||||
|
@ -2280,6 +2289,8 @@
|
|||
<string name="pref_wide_area_tap_title">Wide area tap</string>
|
||||
<string name="pref_adaptive_volume_control_summary">Increase volume automatically when ambient sound is loud</string>
|
||||
<string name="pref_adaptive_volume_control_title">Adaptive volume control</string>
|
||||
<string name="pref_adaptive_noise_cancelling_title">Adaptive ANC</string>
|
||||
<string name="pref_adaptive_noise_cancelling_summary">Set the strength of the ANC automatically depending on the ambient sound level</string>
|
||||
<string name="sony_speak_to_chat">Speak-to-chat</string>
|
||||
<string name="sony_speak_to_chat_summary">Turn off noise cancelling automatically when you start talking.</string>
|
||||
<string name="sony_speak_to_chat_sensitivity">Voice Detection Sensitivity</string>
|
||||
|
@ -2377,6 +2388,7 @@
|
|||
<string name="huawei_trusleep_title">HUAWEI TruSleep ™</string>
|
||||
<string name="huawei_trusleep_summary">Monitor your sleep quality and breathing pattern in real time.\nAnalyze your sleep patterns and accurately diagnose 6 types of sleeping problems.</string>
|
||||
<string name="huawei_trusleep_summary_light">Improved sleep monitoring</string>
|
||||
<string name="huawei_trusleep_warning">Warning: enabling this will stop sleep from showing up in Gadgetbridge! Click here if you accept this.</string>
|
||||
<string name="prefs_activity_recognition">Activity recognition settings</string>
|
||||
<string name="pref_activity_recognize_running">recognize running</string>
|
||||
<string name="pref_activity_recognize_biking">recognize biking</string>
|
||||
|
|
18
app/src/main/res/xml/devicesettings_hplus.xml
Normal file
18
app/src/main/res/xml/devicesettings_hplus.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="5"
|
||||
android:icon="@drawable/ic_always_on_display"
|
||||
android:key="hplus_screentime"
|
||||
android:title="@string/pref_title_screentime"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:icon="@drawable/ic_heart"
|
||||
android:key="hplus_alldayhr"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/prefs_title_all_day_heart_rate" />
|
||||
</PreferenceScreen>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_screen_touch_options"
|
||||
android:persistent="false"
|
||||
android:title="@string/prefs_galaxy_touch_options">
|
||||
</PreferenceScreen>
|
||||
</androidx.preference.PreferenceScreen>
|
76
app/src/main/res/xml/devicesettings_soundcore_headphones.xml
Normal file
76
app/src/main/res/xml/devicesettings_soundcore_headphones.xml
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_header_soundcore_ambient_sound_control"
|
||||
android:title="@string/pref_header_sony_ambient_sound_control">
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="noise_cancelling"
|
||||
android:entries="@array/sony_ambient_sound_control_names"
|
||||
android:entryValues="@array/sony_ambient_sound_control_values"
|
||||
android:icon="@drawable/ic_hearing"
|
||||
android:key="pref_soundcore_ambient_sound_control"
|
||||
android:summary="%s"
|
||||
android:title="@string/sony_ambient_sound" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:disableDependentsState="true"
|
||||
android:icon="@drawable/ic_hearing"
|
||||
android:key="pref_adaptive_noise_cancelling"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/pref_adaptive_noise_cancelling_summary"
|
||||
android:title="@string/pref_adaptive_noise_cancelling_title" />
|
||||
|
||||
<!-- [0, 2], low moderate and high -->
|
||||
<SeekBarPreference
|
||||
android:dependency="pref_adaptive_noise_cancelling"
|
||||
android:defaultValue="0"
|
||||
android:icon="@drawable/ic_hearing"
|
||||
android:key="pref_sony_ambient_sound_level"
|
||||
android:max="2"
|
||||
android:title="@string/prefs_active_noise_cancelling_level" />
|
||||
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_block"
|
||||
android:key="pref_soundcore_wind_noise_reduction"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/sony_ambient_sound_wind_noise_reduction" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_voice"
|
||||
android:key="pref_soundcore_transparency_vocal_mode"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/sony_ambient_sound_focus_voice" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="pref_key_header_soundcore_other"
|
||||
android:title="@string/pref_header_other">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/nothing_prefs_inear_summary"
|
||||
android:title="@string/nothing_prefs_inear_title"/>
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="pref_soundcore_wearing_tone"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/pref_wearing_tone_summary"
|
||||
android:title="@string/pref_wearing_tone"/>
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="pref_soundcore_touch_tone"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/pref_touch_tone_summary"
|
||||
android:title="@string/pref_touch_tone"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
107
app/src/main/res/xml/devicesettings_soundcore_touch_options.xml
Normal file
107
app/src/main/res/xml/devicesettings_soundcore_touch_options.xml
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:title="@string/single_tap">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:disableDependentsState="true"
|
||||
android:icon="@drawable/ic_lock_open"
|
||||
android:key="pref_soundcore_control_single_tap_disabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_touch_lock_summary"
|
||||
android:title="@string/prefs_touch_lock" />
|
||||
<ListPreference
|
||||
android:dependency="pref_soundcore_control_single_tap_disabled"
|
||||
android:entries="@array/soundcore_button_function_names"
|
||||
android:entryValues="@array/soundcore_button_function_values"
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_soundcore_control_single_tap_action_left"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_left" />
|
||||
<ListPreference
|
||||
android:dependency="pref_soundcore_control_single_tap_disabled"
|
||||
android:entries="@array/soundcore_button_function_names"
|
||||
android:entryValues="@array/soundcore_button_function_values"
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_soundcore_control_single_tap_action_right"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_right" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/double_tap">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:disableDependentsState="true"
|
||||
android:icon="@drawable/ic_lock_open"
|
||||
android:key="pref_soundcore_control_double_tap_disabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_touch_lock_summary"
|
||||
android:title="@string/prefs_touch_lock" />
|
||||
<ListPreference
|
||||
android:dependency="pref_soundcore_control_double_tap_disabled"
|
||||
android:entries="@array/soundcore_button_function_names"
|
||||
android:entryValues="@array/soundcore_button_function_values"
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_soundcore_control_double_tap_action_left"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_left" />
|
||||
<ListPreference
|
||||
android:dependency="pref_soundcore_control_double_tap_disabled"
|
||||
android:entries="@array/soundcore_button_function_names"
|
||||
android:entryValues="@array/soundcore_button_function_values"
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_soundcore_control_double_tap_action_right"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_right" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/triple_tap">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:disableDependentsState="true"
|
||||
android:icon="@drawable/ic_lock_open"
|
||||
android:key="pref_soundcore_control_triple_tap_disabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_touch_lock_summary"
|
||||
android:title="@string/prefs_touch_lock" />
|
||||
<ListPreference
|
||||
android:dependency="pref_soundcore_control_triple_tap_disabled"
|
||||
android:entries="@array/soundcore_button_function_names"
|
||||
android:entryValues="@array/soundcore_button_function_values"
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_soundcore_control_triple_tap_action_left"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_left" />
|
||||
<ListPreference
|
||||
android:dependency="pref_soundcore_control_triple_tap_disabled"
|
||||
android:entries="@array/soundcore_button_function_names"
|
||||
android:entryValues="@array/soundcore_button_function_values"
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_soundcore_control_triple_tap_action_right"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_right" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/long_press">
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:disableDependentsState="true"
|
||||
android:icon="@drawable/ic_lock_open"
|
||||
android:key="pref_soundcore_control_long_press_disabled"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:summary="@string/prefs_touch_lock_summary"
|
||||
android:title="@string/prefs_touch_lock" />
|
||||
<ListPreference
|
||||
android:dependency="pref_soundcore_control_long_press_disabled"
|
||||
android:entries="@array/soundcore_button_function_names"
|
||||
android:entryValues="@array/soundcore_button_function_values"
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_soundcore_control_long_press_action_left"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_left" />
|
||||
<ListPreference
|
||||
android:dependency="pref_soundcore_control_long_press_disabled"
|
||||
android:entries="@array/soundcore_button_function_names"
|
||||
android:entryValues="@array/soundcore_button_function_values"
|
||||
android:icon="@drawable/ic_touch"
|
||||
android:key="pref_soundcore_control_long_press_action_right"
|
||||
android:summary="%s"
|
||||
android:title="@string/prefs_right" />
|
||||
</PreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -1,19 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_access_time"
|
||||
android:icon="@drawable/ic_activity_sleep"
|
||||
android:key="screen_trusleep"
|
||||
android:persistent="false"
|
||||
android:title="@string/huawei_trusleep_title"
|
||||
android:summary="@string/huawei_trusleep_summary_light">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:icon="@drawable/ic_access_time"
|
||||
android:defaultValue="false"
|
||||
android:key="trusleep"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_activity_sleep"
|
||||
android:key="screen_trusleep_warning"
|
||||
android:title="@string/huawei_trusleep_title"
|
||||
android:summary="@string/huawei_trusleep_summary"/>
|
||||
android:summary="@string/huawei_trusleep_warning">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:icon="@drawable/ic_activity_sleep"
|
||||
android:defaultValue="false"
|
||||
android:key="trusleep"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/huawei_trusleep_title"
|
||||
android:summary="@string/huawei_trusleep_summary"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
</PreferenceScreen>
|
||||
</androidx.preference.PreferenceScreen>
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceCategory
|
||||
android:key="pref_category_hplus_general"
|
||||
android:title="@string/pref_header_general"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="5"
|
||||
android:key="hplus_screentime"
|
||||
android:title="@string/pref_title_screentime"
|
||||
app:iconSpaceReserved="false"
|
||||
app:useSimpleSummaryProvider="true"/>
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="hplus_alldayhr"
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/prefs_title_all_day_heart_rate"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
|
@ -285,11 +285,6 @@
|
|||
android:key="pref_key_pebble"
|
||||
android:title="@string/pref_title_pebble_settings">
|
||||
</Preference>
|
||||
<Preference
|
||||
android:icon="@drawable/ic_device_hplus"
|
||||
android:key="pref_key_hplus"
|
||||
android:title="@string/preferences_hplus_settings">
|
||||
</Preference>
|
||||
<Preference
|
||||
android:icon="@drawable/ic_device_zetime"
|
||||
android:key="pref_key_zetime"
|
||||
|
|
|
@ -259,6 +259,14 @@ public class TestWorkout {
|
|||
byte backFootLanding2 = 0x26;
|
||||
byte eversionAngle2 = 0x27;
|
||||
|
||||
// TODO: Add:
|
||||
// - swolf
|
||||
// - stoke rate
|
||||
// - calories
|
||||
// - cycling power
|
||||
// - frequency
|
||||
// - altitude
|
||||
|
||||
ByteBuffer headerBuf = ByteBuffer.allocate(14);
|
||||
headerBuf.putShort(workoutNumber);
|
||||
headerBuf.putShort(dataNumber);
|
||||
|
|
|
@ -33,6 +33,19 @@ public class ArmenianTransliteratorTest extends TestCase {
|
|||
new ArmenianTransliterator().transliterate("որը jet iridescent կառուցում են sheen Վիքիպեդիա կայքից օգտվողները and a distinctive ազատ խմբագրման ձևաչափով"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMixedCaseWords() {
|
||||
Assert.assertEquals(
|
||||
"Inchpes", new ArmenianTransliterator().transliterate("Ինչպես")
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"VOrՕSHEL", new ArmenianTransliterator().transliterate("ՈրՈՇԵԼ")
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"Ushadir", new ArmenianTransliterator().transliterate("Ուշադիր")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testTop100Words() {
|
||||
|
|
|
@ -53,7 +53,7 @@ public class LanguageUtilsTest extends TestBase {
|
|||
final Map<String, String> tests = new LinkedHashMap<String, String>() {{
|
||||
put("Тхе qицк брон фоx јумпед овер тхе лаз* дог", "The qick bron fox jumped over the laz* dog");
|
||||
put("Српска ћирилица", "Srpska cirilica");
|
||||
put("Novak Đoković", "Novak Dokovic");
|
||||
put("Novak Đoković", "Novak Djokovic");
|
||||
put("Џ, Њ and Љ", "Dz, Nj and Lj");
|
||||
put("Љуљачка", "Ljuljacka");
|
||||
put("Наковањ", "Nakovanj");
|
||||
|
@ -63,7 +63,7 @@ public class LanguageUtilsTest extends TestBase {
|
|||
put("Ћ, ћ", "C, c");
|
||||
put("Ж, ж", "Z, z");
|
||||
put("Ш, ш", "S, s");
|
||||
put("Ђ, ђ", "D, d");
|
||||
put("Ђ, ђ", "Dj, dj");
|
||||
put("Џ, џ", "Dz, dz");
|
||||
put("Њ, њ", "Nj, nj");
|
||||
put("Љ, љ", "Lj, lj");
|
||||
|
|
Loading…
Reference in New Issue
Block a user