mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-10 17:11:56 +01:00
Merge branch 'master' of https://codeberg.org/Freeyourgadget/Gadgetbridge
Conflicts: GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java
This commit is contained in:
commit
61da55e0de
20
CHANGELOG.md
20
CHANGELOG.md
@ -1,4 +1,24 @@
|
||||
### Changelog
|
||||
|
||||
#### Version 0.43.2
|
||||
* Fossil Hybrid HR: Allow choosing and cropping image to be set as watch background
|
||||
* Fossil Hybrid HR: Option to draw circles around widgets
|
||||
* Fossil Hybrid HR: Experimenal firmware update support
|
||||
* Fossil Hybrid HR: Fix vibration strength setting
|
||||
* Huami: Do not display firmware information and whitelist information when flashing watchfaces
|
||||
* Huami: Disable air quality indicator on Huami devices instead of showing 0
|
||||
* Bangle.js: Change encoded char set to match Espruino's 8 bit fonts
|
||||
* Steps/Sleep averages: Skip days with zero data
|
||||
|
||||
#### Version 0.43.1
|
||||
* Initial support for Amazfit Bip S (incomplete, needs the official app once to obtain the pairing key)
|
||||
* Amazift Bip Lite: Allow relaxing firmware checks to allow flashing of the regular Bip firmware (for the brave)
|
||||
* Fossil Hybrid HR: Fix notification history on newer firmwares
|
||||
* Fossil Hybrid HR: Add option to disable widget circle
|
||||
* Bangle.js: Don't set time if the option is turned off in settings
|
||||
* Bangle.js: DST and time zone fixes
|
||||
* Add Arabic-style Eastern Arabic numerals to transliteration
|
||||
|
||||
#### Version 0.43.0
|
||||
* Initial support for Fossil Hybrid HR (needs complicated key extraction, read wiki)
|
||||
* Fossil: Allow switching off the Q Icon and use the default Gadgetbridge icon
|
||||
|
@ -43,7 +43,7 @@ public class GBDaoGenerator {
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Schema schema = new Schema(24, MAIN_PACKAGE + ".entities");
|
||||
Schema schema = new Schema(25, MAIN_PACKAGE + ".entities");
|
||||
|
||||
Entity userAttributes = addUserAttributes(schema);
|
||||
Entity user = addUserInfo(schema, userAttributes);
|
||||
@ -74,6 +74,7 @@ public class GBDaoGenerator {
|
||||
addWatchXPlusHealthActivitySample(schema, user, device);
|
||||
addWatchXPlusHealthActivityKindOverlay(schema, user, device);
|
||||
|
||||
addHybridHRActivitySample(schema, user, device);
|
||||
addCalendarSyncState(schema, device);
|
||||
addAlarms(schema, user, device);
|
||||
|
||||
@ -344,6 +345,23 @@ public class GBDaoGenerator {
|
||||
return activitySample;
|
||||
}
|
||||
|
||||
private static Entity addHybridHRActivitySample(Schema schema, Entity user, Entity device) {
|
||||
Entity activitySample = addEntity(schema, "HybridHRActivitySample");
|
||||
activitySample.implementsSerializable();
|
||||
|
||||
addCommonActivitySampleProperties("AbstractHybridHRActivitySample", activitySample, user, device);
|
||||
|
||||
activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
activitySample.addIntProperty("calories").notNull();
|
||||
activitySample.addIntProperty("variability").notNull();
|
||||
activitySample.addIntProperty("max_variability").notNull();
|
||||
activitySample.addIntProperty("heartrate_quality").notNull();
|
||||
activitySample.addBooleanProperty("active").notNull();
|
||||
activitySample.addByteProperty("wear_type").notNull();
|
||||
addHeartRateProperties(activitySample);
|
||||
return activitySample;
|
||||
}
|
||||
|
||||
private static Entity addWatchXPlusHealthActivitySample(Schema schema, Entity user, Entity device) {
|
||||
Entity activitySample = addEntity(schema, "WatchXPlusActivitySample");
|
||||
activitySample.implementsSerializable();
|
||||
|
12
README.md
12
README.md
@ -27,15 +27,17 @@ vendor's servers.
|
||||
|
||||
[List of changes](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/CHANGELOG.md)
|
||||
|
||||
## Supported Devices (Some of them WIP and some of them without maintainer)
|
||||
## Supported Devices (WARNING: Some of them WIP and some of them without maintainer)
|
||||
* Amazfit Bip [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip)
|
||||
* Amazfit Bip Lite (NOT RECOMMENDED, NEEDS MI FIT WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-Lite)
|
||||
* Amazfit Bip Lite (WARNING: NEEDS MI FIT WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-Lite)
|
||||
* Amazfit Bip S (WARNING: NEEDS MI FIT WITH ACCOUNT ONCE)
|
||||
* Amazfit Cor [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor)
|
||||
* Amazfit Cor 2 [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor-2)
|
||||
* Amazfit GTR (NOT RECOMMENDED, NEEDS MI FIT WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR)
|
||||
* Amazfit GTS (NOT RECOMMENDED, NEEDS MI FIT WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS)
|
||||
* Amazfit GTR (WARNING: NEEDS MI FIT WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR)
|
||||
* Amazfit GTS (WARNING: NEEDS MI FIT WITH ACCOUNT ONCE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS)
|
||||
* BFH-16
|
||||
* Casio GB-6900B
|
||||
* Fossil Hybrid HR (WARNING: NEEDS FOSSIL APP WITH ACCOUNT ONCE AND COMPLICATED PROCEDURE) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Fossil-Hybrid-HR)
|
||||
* Fossil Q Hybrid
|
||||
* HPlus Devices (e.g. ZeBand) [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/HPlus)
|
||||
* iTag
|
||||
@ -83,7 +85,7 @@ Please see [FEATURES.md](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/ma
|
||||
* Jean-François Greffier (Mi Scale 2)
|
||||
* Johannes Schmitt (BFH-16)
|
||||
* Lukas Schwichtenberg (Makibes HR3)
|
||||
* Daniel Dakhno (Fossil Q Hybrid)
|
||||
* Daniel Dakhno (Fossil Q Hybrid, Fossil Hybrid HR)
|
||||
* Gordon Williams (Bangle.js)
|
||||
* Pavel Elagin (JYou Y5)
|
||||
* Taavi Eomäe (iTag)
|
||||
|
@ -25,8 +25,8 @@ android {
|
||||
targetSdkVersion 28
|
||||
|
||||
// Note: always bump BOTH versionCode and versionName!
|
||||
versionName "0.43.0"
|
||||
versionCode 169
|
||||
versionName "0.43.2"
|
||||
versionCode 171
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
buildTypes {
|
||||
|
@ -517,6 +517,9 @@
|
||||
<activity
|
||||
android:name=".devices.qhybrid.HRConfigActivity"
|
||||
android:exported="true" />
|
||||
<activity
|
||||
android:name=".devices.qhybrid.ImageEditActivity"
|
||||
android:exported="true" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -59,6 +59,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
||||
public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(AbstractWeekChartFragment.class);
|
||||
protected final int TOTAL_DAYS = getRangeDays();
|
||||
protected int TOTAL_DAYS_FOR_AVERAGE = 0;
|
||||
|
||||
private Locale mLocale;
|
||||
private int mTargetValue = 0;
|
||||
@ -124,10 +125,17 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
||||
ArrayList<String> labels = new ArrayList<String>();
|
||||
|
||||
long balance = 0;
|
||||
long daily_balance=0;
|
||||
TOTAL_DAYS_FOR_AVERAGE=0;
|
||||
|
||||
for (int counter = 0; counter < TOTAL_DAYS; counter++) {
|
||||
ActivityAmounts amounts = getActivityAmountsForDay(db, day, device);
|
||||
daily_balance=calculateBalance(amounts);
|
||||
if (daily_balance>0){
|
||||
TOTAL_DAYS_FOR_AVERAGE++;
|
||||
}
|
||||
|
||||
balance += calculateBalance(amounts);
|
||||
balance += daily_balance;
|
||||
entries.add(new BarEntry(counter, getTotalsForActivityAmounts(amounts)));
|
||||
labels.add(getWeeksChartsLabel(day));
|
||||
day.add(Calendar.DATE, 1);
|
||||
@ -146,8 +154,8 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
||||
barChart.getAxisLeft().addLimitLine(target);
|
||||
|
||||
float average = 0;
|
||||
if (TOTAL_DAYS > 0) {
|
||||
average = Math.abs(balance / TOTAL_DAYS);
|
||||
if (TOTAL_DAYS_FOR_AVERAGE > 0) {
|
||||
average = Math.abs(balance / TOTAL_DAYS_FOR_AVERAGE);
|
||||
}
|
||||
LimitLine average_line = new LimitLine(average);
|
||||
average_line.setLabel(getString(R.string.average, getAverage(average)));
|
||||
|
@ -76,7 +76,7 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
@Override
|
||||
protected String getBalanceMessage(long balance, int targetValue) {
|
||||
if (balance > 0) {
|
||||
final long totalBalance = balance - ((long)targetValue * TOTAL_DAYS);
|
||||
final long totalBalance = balance - ((long)targetValue * TOTAL_DAYS_FOR_AVERAGE);
|
||||
if (totalBalance > 0)
|
||||
return getString(R.string.overslept, getHM(totalBalance));
|
||||
else
|
||||
|
@ -109,7 +109,7 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment {
|
||||
@Override
|
||||
protected String getBalanceMessage(long balance, int targetValue) {
|
||||
if (balance > 0) {
|
||||
final long totalBalance = balance - ((long)targetValue * TOTAL_DAYS);
|
||||
final long totalBalance = balance - ((long)targetValue * TOTAL_DAYS_FOR_AVERAGE);
|
||||
if (totalBalance > 0)
|
||||
return getString(R.string.overstep, Math.abs(totalBalance));
|
||||
else
|
||||
|
@ -29,4 +29,8 @@ public class DeviceSettingsPreferenceConst {
|
||||
public static final String PREF_BUTTON_2_FUNCTION = "button_2_function";
|
||||
public static final String PREF_BUTTON_3_FUNCTION = "button_3_function";
|
||||
public static final String PREF_VIBRATION_STRENGH_PERCENTAGE = "vibration_strength";
|
||||
public static final String PREF_RELAX_FIRMWARE_CHECKS = "relax_firmware_checks";
|
||||
|
||||
public static final String PREF_HYBRID_HR_FORCE_WHITE_COLOR = "force_white_color_scheme";
|
||||
public static final String PREF_HYBRID_HR_DRAW_WIDGET_CIRCLES = "widget_draw_circles";
|
||||
}
|
@ -43,6 +43,8 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BUTTON_2_FUNCTION;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BUTTON_3_FUNCTION;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DATEFORMAT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYBRID_HR_DRAW_WIDGET_CIRCLES;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYBRID_HR_FORCE_WHITE_COLOR;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SCREEN_ORIENTATION;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_TIMEFORMAT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_VIBRATION_STRENGH_PERCENTAGE;
|
||||
@ -322,6 +324,9 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat {
|
||||
addPreferenceHandlerFor(PREF_BUTTON_3_FUNCTION);
|
||||
addPreferenceHandlerFor(PREF_VIBRATION_STRENGH_PERCENTAGE);
|
||||
|
||||
addPreferenceHandlerFor(PREF_HYBRID_HR_DRAW_WIDGET_CIRCLES);
|
||||
addPreferenceHandlerFor(PREF_HYBRID_HR_FORCE_WHITE_COLOR);
|
||||
|
||||
String displayOnLiftState = prefs.getString(PREF_ACTIVATE_DISPLAY_ON_LIFT, PREF_DO_NOT_DISTURB_OFF);
|
||||
boolean displayOnLiftScheduled = displayOnLiftState.equals(PREF_DO_NOT_DISTURB_SCHEDULED);
|
||||
|
||||
|
@ -28,6 +28,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
||||
|
||||
public abstract class HuamiFWHelper extends AbstractMiBandFWHelper {
|
||||
protected HuamiFirmwareInfo firmwareInfo;
|
||||
@ -110,6 +111,10 @@ public abstract class HuamiFWHelper extends AbstractMiBandFWHelper {
|
||||
firmwareInfo.checkValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HuamiFirmwareType getFirmwareType() {
|
||||
return firmwareInfo.getFirmwareType();
|
||||
}
|
||||
public HuamiFirmwareInfo getFirmwareInfo() {
|
||||
return firmwareInfo;
|
||||
}
|
||||
|
@ -26,7 +26,9 @@ import androidx.annotation.NonNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
|
||||
@ -63,4 +65,21 @@ public class AmazfitBipLiteCoordinator extends AmazfitBipCoordinator {
|
||||
public int getBondingStyle() {
|
||||
return BONDING_STYLE_REQUIRE_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
||||
return new int[]{
|
||||
R.xml.devicesettings_amazfitbip,
|
||||
R.xml.devicesettings_timeformat,
|
||||
R.xml.devicesettings_wearlocation,
|
||||
R.xml.devicesettings_custom_emoji_font,
|
||||
R.xml.devicesettings_liftwrist_display,
|
||||
R.xml.devicesettings_disconnectnotification,
|
||||
R.xml.devicesettings_sync_calendar,
|
||||
R.xml.devicesettings_expose_hr_thirdparty,
|
||||
R.xml.devicesettings_buttonactions_with_longpress,
|
||||
R.xml.devicesettings_pairingkey,
|
||||
R.xml.devicesettings_relax_firmware_checks,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,99 @@
|
||||
/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, João Paulo Barraca, Nephiel, vanous
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbips;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
|
||||
public class AmazfitBipSCoordinator extends HuamiCoordinator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitBipSCoordinator.class);
|
||||
|
||||
@Override
|
||||
public DeviceType getDeviceType() {
|
||||
return DeviceType.AMAZFITBIPS;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DeviceType getSupportedType(GBDeviceCandidate candidate) {
|
||||
try {
|
||||
BluetoothDevice device = candidate.getDevice();
|
||||
String name = device.getName();
|
||||
if (name != null && (name.equalsIgnoreCase("Amazfit Bip S"))) {
|
||||
return DeviceType.AMAZFITBIPS;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LOG.error("unable to check device support", ex);
|
||||
}
|
||||
return DeviceType.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallHandler findInstallHandler(Uri uri, Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsHeartRateMeasurement(GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsActivityTracks() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsWeather() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
||||
return new int[]{
|
||||
R.xml.devicesettings_amazfitbip,
|
||||
R.xml.devicesettings_timeformat,
|
||||
R.xml.devicesettings_wearlocation,
|
||||
R.xml.devicesettings_custom_emoji_font,
|
||||
R.xml.devicesettings_liftwrist_display,
|
||||
R.xml.devicesettings_disconnectnotification,
|
||||
R.xml.devicesettings_sync_calendar,
|
||||
R.xml.devicesettings_expose_hr_thirdparty,
|
||||
R.xml.devicesettings_buttonactions_with_longpress,
|
||||
R.xml.devicesettings_pairingkey
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBondingStyle() {
|
||||
return BONDING_STYLE_REQUIRE_KEY;
|
||||
}
|
||||
}
|
@ -22,7 +22,6 @@ import android.net.Uri;
|
||||
import java.io.IOException;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr.AmazfitGTRFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
@ -40,7 +39,7 @@ class AmazfitGTSFWInstallHandler extends AbstractMiBandFWInstallHandler {
|
||||
|
||||
@Override
|
||||
protected AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException {
|
||||
return new AmazfitGTRFWHelper(uri, context);
|
||||
return new AmazfitGTSFWHelper(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,6 +31,7 @@ import androidx.annotation.NonNull;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
|
||||
|
||||
@ -122,4 +123,6 @@ public abstract class AbstractMiBandFWHelper {
|
||||
protected abstract void determineFirmwareInfo(byte[] wholeFirmwareBytes);
|
||||
|
||||
public abstract void checkValid() throws IllegalArgumentException;
|
||||
|
||||
public abstract HuamiFirmwareType getFirmwareType();
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType.WATCHFACE;
|
||||
|
||||
public abstract class AbstractMiBandFWInstallHandler implements InstallHandler {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractMiBandFWInstallHandler.class);
|
||||
|
||||
@ -58,7 +60,7 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler {
|
||||
|
||||
protected abstract AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException;
|
||||
|
||||
protected GenericItem createInstallItem(GBDevice device) {
|
||||
private GenericItem createInstallItem(GBDevice device) {
|
||||
return new GenericItem(mContext.getString(R.string.installhandler_firmware_name, mContext.getString(device.getType().getName()), helper.getFirmwareKind(), helper.getHumanFirmwareVersion()));
|
||||
}
|
||||
|
||||
@ -98,23 +100,25 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler {
|
||||
return;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (helper.isSingleFirmware()) {
|
||||
getFwUpgradeNotice();
|
||||
builder.append(getFwUpgradeNotice());
|
||||
} else {
|
||||
builder.append(mContext.getString(R.string.fw_multi_upgrade_notice, helper.getHumanFirmwareVersion(), helper.getHumanFirmwareVersion2()));
|
||||
}
|
||||
if (helper.getFirmwareType() != WATCHFACE) {
|
||||
if (helper.isSingleFirmware()) {
|
||||
getFwUpgradeNotice();
|
||||
builder.append(getFwUpgradeNotice());
|
||||
} else {
|
||||
builder.append(mContext.getString(R.string.fw_multi_upgrade_notice, helper.getHumanFirmwareVersion(), helper.getHumanFirmwareVersion2()));
|
||||
}
|
||||
|
||||
|
||||
if (helper.isFirmwareWhitelisted()) {
|
||||
builder.append(" ").append(mContext.getString(R.string.miband_firmware_known));
|
||||
fwItem.setDetails(mContext.getString(R.string.miband_fwinstaller_compatible_version));
|
||||
// TODO: set a CHECK (OKAY) button
|
||||
} else {
|
||||
builder.append(" ").append(mContext.getString(R.string.miband_firmware_unknown_warning)).append(" \n\n")
|
||||
.append(mContext.getString(R.string.miband_firmware_suggest_whitelist, String.valueOf(helper.getFirmwareVersion())));
|
||||
fwItem.setDetails(mContext.getString(R.string.miband_fwinstaller_untested_version));
|
||||
// TODO: set a UNKNOWN (question mark) button
|
||||
if (helper.isFirmwareWhitelisted()) {
|
||||
builder.append(" ").append(mContext.getString(R.string.miband_firmware_known));
|
||||
fwItem.setDetails(mContext.getString(R.string.miband_fwinstaller_compatible_version));
|
||||
// TODO: set a CHECK (OKAY) button
|
||||
} else {
|
||||
builder.append(" ").append(mContext.getString(R.string.miband_firmware_unknown_warning)).append(" \n\n")
|
||||
.append(mContext.getString(R.string.miband_firmware_suggest_whitelist, String.valueOf(helper.getFirmwareVersion())));
|
||||
fwItem.setDetails(mContext.getString(R.string.miband_fwinstaller_untested_version));
|
||||
// TODO: set a UNKNOWN (question mark) button
|
||||
}
|
||||
}
|
||||
installActivity.setInfoText(builder.toString());
|
||||
installActivity.setInstallItem(fwItem);
|
||||
|
@ -29,6 +29,7 @@ import androidx.annotation.NonNull;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.AbstractMiFirmwareInfo;
|
||||
|
||||
/**
|
||||
@ -122,6 +123,11 @@ public class MiBandFWHelper extends AbstractMiBandFWHelper {
|
||||
firmwareInfo.checkValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HuamiFirmwareType getFirmwareType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param wholeFirmwareBytes
|
||||
* @return
|
||||
|
@ -0,0 +1,111 @@
|
||||
/* Copyright (C) 2020 Andreas Shimokawa
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
|
||||
|
||||
public class FossilHRInstallHandler implements InstallHandler {
|
||||
private final Context mContext;
|
||||
private boolean mIsValid;
|
||||
private String mVersion = "(Unknown version)";
|
||||
|
||||
FossilHRInstallHandler(Uri uri, Context context) {
|
||||
mContext = context;
|
||||
UriHelper uriHelper;
|
||||
try {
|
||||
uriHelper = UriHelper.get(uri, mContext);
|
||||
} catch (IOException e) {
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
try (InputStream in = new BufferedInputStream(uriHelper.openInputStream())) {
|
||||
byte[] bytes = new byte[32];
|
||||
int read = in.read(bytes);
|
||||
if (read < 32) {
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuffer buf = ByteBuffer.wrap(bytes);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
int header0 = buf.getInt();
|
||||
buf.getInt(); // size
|
||||
int header2 = buf.getInt();
|
||||
int header3 = buf.getInt();
|
||||
if (header0 != 1 || header2 != 0x00012000 || header3 != 0x00012000) {
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
buf.getInt(); // unknown
|
||||
int version1 = buf.get() % 0xff;
|
||||
int version2 = buf.get() & 0xff;
|
||||
mVersion = "DN1.0." + version1 + "." + version2;
|
||||
} catch (Exception e) {
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
mIsValid = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateInstallation(InstallActivity installActivity, GBDevice device) {
|
||||
if (device.isBusy()) {
|
||||
installActivity.setInfoText(device.getBusyTask());
|
||||
installActivity.setInstallEnabled(false);
|
||||
return;
|
||||
}
|
||||
if (device.getType() != DeviceType.FOSSILQHYBRID || !device.isConnected()) {
|
||||
installActivity.setInfoText("Element cannot be installed");
|
||||
installActivity.setInstallEnabled(false);
|
||||
return;
|
||||
}
|
||||
GenericItem installItem = new GenericItem();
|
||||
installItem.setIcon(R.drawable.ic_firmware);
|
||||
installItem.setName("Fossil Hybrid HR Firmware");
|
||||
installItem.setDetails(mVersion);
|
||||
|
||||
installActivity.setInfoText(mContext.getString(R.string.firmware_install_warning, "(unknown)"));
|
||||
installActivity.setInstallEnabled(true);
|
||||
installActivity.setInstallItem(installItem);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStartInstall(GBDevice device) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return mIsValid;
|
||||
}
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -26,6 +30,7 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -53,6 +58,9 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick
|
||||
SparseArray<String> widgetButtonsMapping = new SparseArray<>(4);
|
||||
|
||||
static public final String CONFIG_KEY_Q_ACTIONS = "Q_ACTIONS";
|
||||
private static final int REQUEST_CODE_WIDGET_EDIT = 0;
|
||||
private static final int REQUEST_CODE_IMAGE_PICK = 1;
|
||||
private static final int REQUEST_CODE_IMAGE_EDIT = 2;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -84,7 +92,7 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick
|
||||
startIntent.putExtra("EXTRA_WIDGET", widget);
|
||||
startIntent.putExtra("EXTRA_WIDGET_IDNEX", position);
|
||||
|
||||
startActivityForResult(startIntent, 0);
|
||||
startActivityForResult(startIntent, REQUEST_CODE_WIDGET_EDIT);
|
||||
}
|
||||
});
|
||||
loadCustomWidgetList();
|
||||
@ -94,7 +102,36 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick
|
||||
public void onClick(View v) {
|
||||
Intent startIntent = new Intent(HRConfigActivity.this, WidgetSettingsActivity.class);
|
||||
|
||||
startActivityForResult(startIntent, 0);
|
||||
startActivityForResult(startIntent, REQUEST_CODE_WIDGET_EDIT);
|
||||
}
|
||||
});
|
||||
|
||||
findViewById(R.id.qhybrid_set_background).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
new AlertDialog.Builder(HRConfigActivity.this)
|
||||
.setTitle("whoop whoop")
|
||||
.setMessage("background has to be pushed every time a custom widget changes, causing traffic and battery drain. Consider that when using custom widgets.")
|
||||
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK);
|
||||
pickIntent.setType("image/*");
|
||||
|
||||
startActivityForResult(pickIntent, REQUEST_CODE_IMAGE_PICK);
|
||||
}
|
||||
})
|
||||
.setNegativeButton("nah", null)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
|
||||
findViewById(R.id.qhybrid_unset_background).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent intent = new Intent(QHybridSupport.QHYBRID_COMMAND_SET_BACKGROUND_IMAGE);
|
||||
intent.putIntegerArrayListExtra("EXTRA_PIXELS", null);
|
||||
LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(intent);
|
||||
}
|
||||
});
|
||||
|
||||
@ -138,34 +175,50 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick
|
||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if(data == null) return;
|
||||
if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_CREATED) {
|
||||
CustomWidget widget = (CustomWidget) data.getExtras().get("EXTRA_WIDGET");
|
||||
this.customWidgets.add(widget);
|
||||
refreshWidgetList();
|
||||
saveCustomWidgetList();
|
||||
if(requestCode == REQUEST_CODE_WIDGET_EDIT) {
|
||||
if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_CREATED) {
|
||||
CustomWidget widget = (CustomWidget) data.getExtras().get("EXTRA_WIDGET");
|
||||
this.customWidgets.add(widget);
|
||||
refreshWidgetList();
|
||||
saveCustomWidgetList();
|
||||
|
||||
LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS));
|
||||
} else if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_UPDATED) {
|
||||
CustomWidget widget = (CustomWidget) data.getExtras().get("EXTRA_WIDGET");
|
||||
int updateIndex = data.getIntExtra("EXTRA_WIDGET_IDNEX", -1);
|
||||
LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS));
|
||||
} else if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_UPDATED) {
|
||||
CustomWidget widget = (CustomWidget) data.getExtras().get("EXTRA_WIDGET");
|
||||
int updateIndex = data.getIntExtra("EXTRA_WIDGET_IDNEX", -1);
|
||||
|
||||
this.customWidgets.set(updateIndex, widget);
|
||||
this.customWidgets.set(updateIndex, widget);
|
||||
|
||||
refreshWidgetList();
|
||||
saveCustomWidgetList();
|
||||
refreshWidgetList();
|
||||
saveCustomWidgetList();
|
||||
|
||||
LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS));
|
||||
} else if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_DELETED){
|
||||
int updateIndex = data.getIntExtra("EXTRA_WIDGET_IDNEX", -1);
|
||||
LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS));
|
||||
} else if (resultCode == WidgetSettingsActivity.RESULT_CODE_WIDGET_DELETED) {
|
||||
int updateIndex = data.getIntExtra("EXTRA_WIDGET_IDNEX", -1);
|
||||
|
||||
this.customWidgets.remove(updateIndex);
|
||||
this.customWidgets.remove(updateIndex);
|
||||
|
||||
refreshWidgetList();
|
||||
saveCustomWidgetList();
|
||||
refreshWidgetList();
|
||||
saveCustomWidgetList();
|
||||
|
||||
LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS));
|
||||
LocalBroadcastManager.getInstance(HRConfigActivity.this).sendBroadcast(new Intent(QHYBRID_COMMAND_UPDATE_WIDGETS));
|
||||
}
|
||||
}else if(requestCode == REQUEST_CODE_IMAGE_PICK){
|
||||
if (resultCode == RESULT_OK)
|
||||
{
|
||||
Uri imageUri = data.getData();
|
||||
Intent activityIntent = new Intent();
|
||||
activityIntent.setClass(this, ImageEditActivity.class);
|
||||
activityIntent.setData(imageUri);
|
||||
|
||||
startActivityForResult(activityIntent, REQUEST_CODE_IMAGE_EDIT);
|
||||
}
|
||||
}else if(requestCode == REQUEST_CODE_IMAGE_EDIT){
|
||||
if(resultCode == ImageEditActivity.RESULT_CODE_EDIT_SUCCESS){
|
||||
data.setAction(QHybridSupport.QHYBRID_COMMAND_SET_BACKGROUND_IMAGE);
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void saveCustomWidgetList() {
|
||||
@ -474,6 +527,7 @@ public class HRConfigActivity extends AbstractGBActivity implements View.OnClick
|
||||
super(HRConfigActivity.this, 0, objects);
|
||||
}
|
||||
|
||||
@SuppressLint("ResourceType")
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||
|
@ -0,0 +1,75 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.greenrobot.dao.AbstractDao;
|
||||
import de.greenrobot.dao.Property;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
|
||||
|
||||
public class HybridHRActivitySampleProvider extends AbstractSampleProvider<HybridHRActivitySample> {
|
||||
public HybridHRActivitySampleProvider(GBDevice device, DaoSession session) {
|
||||
super(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDao<HybridHRActivitySample, ?> getSampleDao() {
|
||||
return getSession().getHybridHRActivitySampleDao();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Property getRawKindSampleProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getTimestampSampleProperty() {
|
||||
return HybridHRActivitySampleDao.Properties.Timestamp;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getDeviceIdentifierSampleProperty() {
|
||||
return HybridHRActivitySampleDao.Properties.DeviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int normalizeType(int rawType) {
|
||||
if(rawType == -1) return 0;
|
||||
return ActivityEntry.WEARING_STATE.fromValue((byte) rawType).getActivityKind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toRawActivityKind(int activityKind) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float normalizeIntensity(int rawIntensity) {
|
||||
return rawIntensity / 63f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HybridHRActivitySample createActivitySample() {
|
||||
return new HybridHRActivitySample();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HybridHRActivitySample> getActivitySamples(int timestamp_from, int timestamp_to) {
|
||||
return super.getActivitySamples(timestamp_from, timestamp_to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HybridHRActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
||||
return super.getAllActivitySamples(timestamp_from, timestamp_to);
|
||||
}
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImage;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImageFactory;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class ImageEditActivity extends AbstractGBActivity implements View.OnTouchListener {
|
||||
static final public int RESULT_CODE_EDIT_SUCCESS = 0;
|
||||
|
||||
ImageView overlay;
|
||||
Canvas overlayCanvas;
|
||||
Paint overlayPaint;
|
||||
Bitmap overlayBitmap, mainBitmap;
|
||||
|
||||
float x = 0, y = 0, diameter = 0, imageDimension = 0;
|
||||
int imageWidth, imageHeight;
|
||||
|
||||
private enum MovementState {
|
||||
MOVE_UPPER_LEFT,
|
||||
MOVE_LOWER_RIGHT,
|
||||
MOVE_FRAME
|
||||
}
|
||||
private MovementState movementState;
|
||||
float movementStartX, movementStartY, movementStartFrameX, movementStartFrameY, movementStartDiameter, leftUpperDeltaX, leftUpperDeltaY;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_qhybrid_image_edit);
|
||||
|
||||
final RelativeLayout mainLayout = findViewById(R.id.qhybrid_image_edit_container);
|
||||
overlay = findViewById(R.id.qhybrid_image_edit_image_overlay);
|
||||
overlay.setOnTouchListener(this);
|
||||
|
||||
findViewById(R.id.qhybrid_image_edit_okay).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finalizeImage();
|
||||
}
|
||||
});
|
||||
|
||||
mainLayout.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
fitImageToLayout(mainLayout);
|
||||
} catch (IOException | RuntimeException e) {
|
||||
GB.log("Error formatting image", GB.ERROR, e);
|
||||
GB.toast("Error formatting image", Toast.LENGTH_LONG, GB.ERROR);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void finalizeImage(){
|
||||
Bitmap cropped = Bitmap.createBitmap(this.mainBitmap, (int) this.x, (int) this.y, (int) this.diameter, (int) this.diameter);
|
||||
Bitmap scaled = Bitmap.createScaledBitmap(cropped, 400, 400, false);
|
||||
cropped.recycle();
|
||||
|
||||
try {
|
||||
AssetImage image = AssetImageFactory.createAssetImage(scaled, false, 0, 0, 0);
|
||||
|
||||
Intent resultIntent = new Intent();
|
||||
resultIntent.putExtra("EXTRA_PIXELS_ENCODED", image.getFileData());
|
||||
setResult(RESULT_CODE_EDIT_SUCCESS, resultIntent);
|
||||
finish();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
|
||||
scaled.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
private void fitImageToLayout(RelativeLayout mainLayout) throws IOException, RuntimeException {
|
||||
float containerHeight = mainLayout.getHeight();
|
||||
float containerWidth = mainLayout.getWidth();
|
||||
float containerRelation = containerHeight / containerWidth;
|
||||
|
||||
Bitmap bitmap = this.createImageFromURI();
|
||||
float imageHeight = bitmap.getHeight();
|
||||
float imageWidth = bitmap.getWidth();
|
||||
float imageRelation = imageHeight / imageWidth;
|
||||
|
||||
float scaleRatio;
|
||||
if(imageRelation > containerRelation){
|
||||
scaleRatio = containerHeight / imageHeight;
|
||||
}else{
|
||||
scaleRatio = containerWidth / imageWidth;
|
||||
}
|
||||
|
||||
int scaledHeight = (int)(imageHeight * scaleRatio);
|
||||
int scaledWidth = (int)(imageWidth * scaleRatio);
|
||||
|
||||
this.imageHeight = scaledHeight;
|
||||
this.imageWidth = scaledWidth;
|
||||
|
||||
this.imageDimension = this.diameter = Math.min(scaledHeight, scaledWidth);
|
||||
|
||||
mainBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, false);
|
||||
|
||||
ImageView mainImageView = findViewById(R.id.qhybrid_image_edit_image);
|
||||
mainImageView.setImageBitmap(mainBitmap);
|
||||
createOverlay(scaledWidth, scaledHeight);
|
||||
}
|
||||
|
||||
private void createOverlay(int width, int height){
|
||||
this.overlayBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
|
||||
this.overlayCanvas = new Canvas(this.overlayBitmap);
|
||||
|
||||
this.overlayPaint = new Paint();
|
||||
this.overlayPaint.setColor(Color.BLACK);
|
||||
this.overlayPaint.setStyle(Paint.Style.STROKE);
|
||||
this.overlayPaint.setStrokeWidth(imageDimension / 100);
|
||||
|
||||
renderOverlay();
|
||||
}
|
||||
|
||||
private Bitmap createImageFromURI() throws IOException, RuntimeException {
|
||||
Uri imageURI = getIntent().getData();
|
||||
if (imageURI == null) {
|
||||
throw new RuntimeException("no image attached");
|
||||
}
|
||||
|
||||
ContentResolver resolver = getContentResolver();
|
||||
Cursor c = resolver.query(imageURI, new String[]{MediaStore.Images.ImageColumns.ORIENTATION}, null, null, null);
|
||||
c.moveToFirst();
|
||||
int orientation = c.getInt(c.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION));
|
||||
c.close();
|
||||
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageURI);
|
||||
if (orientation != 0) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postRotate(90);
|
||||
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private void renderOverlay() {
|
||||
overlayCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
|
||||
|
||||
overlayCanvas.drawCircle(x, y, imageDimension / 15, overlayPaint);
|
||||
overlayCanvas.drawCircle(x + diameter, y + diameter, imageDimension / 15, overlayPaint);
|
||||
|
||||
overlayCanvas.drawCircle(x + diameter / 2, y + diameter / 2, diameter / 2, overlayPaint);
|
||||
|
||||
overlay.setImageBitmap(overlayBitmap);
|
||||
}
|
||||
|
||||
private void forceImageBoundaries(){
|
||||
this.x = Math.max(this.x, 0);
|
||||
this.y = Math.max(this.y, 0);
|
||||
|
||||
this.x = Math.min(this.x, this.imageWidth - diameter);
|
||||
this.y = Math.min(this.y, this.imageHeight - diameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
|
||||
handleTouchDown(motionEvent);
|
||||
}else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){
|
||||
handleTouchMove(motionEvent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleTouchMove(MotionEvent motionEvent){
|
||||
if(movementState == MovementState.MOVE_UPPER_LEFT){
|
||||
float moveDeltaX = motionEvent.getX() - this.movementStartX;
|
||||
float moveDeltaY = motionEvent.getY() - this.movementStartY;
|
||||
|
||||
float mid = (moveDeltaX + moveDeltaY) / 2;
|
||||
|
||||
this.diameter = this.movementStartDiameter - mid;
|
||||
this.x = this.movementStartX + mid + this.leftUpperDeltaX;
|
||||
this.y = this.movementStartY + mid + this.leftUpperDeltaY;
|
||||
}else if(movementState == MovementState.MOVE_LOWER_RIGHT) {
|
||||
float moveDeltaX = motionEvent.getX() - this.movementStartX;
|
||||
float moveDeltaY = motionEvent.getY() - this.movementStartY;
|
||||
|
||||
float mid = (moveDeltaX + moveDeltaY) / 2;
|
||||
|
||||
this.diameter = this.movementStartDiameter + mid;
|
||||
}else if(movementState == MovementState.MOVE_FRAME){
|
||||
this.x = this.movementStartFrameX + (motionEvent.getX() - this.movementStartX);
|
||||
this.y = this.movementStartFrameY + (motionEvent.getY() - this.movementStartY);
|
||||
}
|
||||
|
||||
this.forceImageBoundaries();
|
||||
renderOverlay();
|
||||
}
|
||||
|
||||
private void handleTouchDown(MotionEvent motionEvent) {
|
||||
this.movementStartX = motionEvent.getX();
|
||||
this.movementStartY = motionEvent.getY();
|
||||
this.movementStartFrameX = this.x;
|
||||
this.movementStartFrameY = this.y;
|
||||
this.movementStartDiameter = this.diameter;
|
||||
|
||||
final float threshold = imageDimension / 15;
|
||||
|
||||
float upperLeftDeltaX = this.x - motionEvent.getX();
|
||||
float upperLeftDeltaY = this.y - motionEvent.getY();
|
||||
|
||||
float upperLeftDistance = (float) Math.sqrt(upperLeftDeltaX * upperLeftDeltaX + upperLeftDeltaY * upperLeftDeltaY);
|
||||
|
||||
if(upperLeftDistance < threshold){
|
||||
// Toast.makeText(this, "upper left", 0).show();
|
||||
this.leftUpperDeltaX = upperLeftDeltaX;
|
||||
this.leftUpperDeltaY = upperLeftDeltaY;
|
||||
this.movementState = MovementState.MOVE_UPPER_LEFT;
|
||||
return;
|
||||
}
|
||||
|
||||
float lowerLeftX = this.x + diameter;
|
||||
float lowerLeftY = this.y + diameter;
|
||||
|
||||
float lowerRightDeltaX = lowerLeftX - motionEvent.getX();
|
||||
float lowerRightDeltaY = lowerLeftY - motionEvent.getY();
|
||||
|
||||
float lowerRightDistance = (float) Math.sqrt(lowerRightDeltaX * lowerRightDeltaX + lowerRightDeltaY * lowerRightDeltaY);
|
||||
|
||||
if(lowerRightDistance < threshold){
|
||||
// Toast.makeText(this, "lower right", 0).show();
|
||||
this.movementState = MovementState.MOVE_LOWER_RIGHT;
|
||||
return;
|
||||
}
|
||||
|
||||
// Toast.makeText(this, "anywhere else", 0).show();
|
||||
this.movementState = MovementState.MOVE_FRAME;
|
||||
}
|
||||
}
|
@ -79,12 +79,13 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
||||
|
||||
@Override
|
||||
public boolean supportsActivityDataFetching() {
|
||||
return true;
|
||||
GBDevice connectedDevice = GBApplication.app().getDeviceManager().getSelectedDevice();
|
||||
return connectedDevice != null && connectedDevice.getType() == DeviceType.FOSSILQHYBRID && connectedDevice.getState() == GBDevice.State.INITIALIZED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsActivityTracking() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,11 +95,15 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
||||
|
||||
@Override
|
||||
public SampleProvider<? extends ActivitySample> getSampleProvider(GBDevice device, DaoSession session) {
|
||||
return null;
|
||||
return new HybridHRActivitySampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallHandler findInstallHandler(Uri uri, Context context) {
|
||||
if (isHybridHR()) {
|
||||
FossilHRInstallHandler installHandler = new FossilHRInstallHandler(uri, context);
|
||||
return installHandler.isValid() ? installHandler : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -127,7 +132,7 @@ public class QHybridCoordinator extends AbstractDeviceCoordinator {
|
||||
|
||||
@Override
|
||||
public boolean supportsHeartRateMeasurement(GBDevice device) {
|
||||
return false;
|
||||
return this.isHybridHR();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,6 +7,8 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
|
@ -0,0 +1,24 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.entities;
|
||||
|
||||
public abstract class AbstractHybridHRActivitySample extends AbstractActivitySample {
|
||||
abstract public int getCalories();
|
||||
abstract public byte getWear_type();
|
||||
|
||||
@Override
|
||||
public int getRawKind() {
|
||||
return getWear_type();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawIntensity() {
|
||||
return getCalories();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserId(long userId) {}
|
||||
|
||||
@Override
|
||||
public long getUserId() {
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -43,6 +43,7 @@ public enum DeviceType {
|
||||
AMAZFITBIP_LITE(17, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_amazfit_bip_lite),
|
||||
AMAZFITGTR(18, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_amazfit_gtr),
|
||||
AMAZFITGTS(19, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_amazfit_gts),
|
||||
AMAZFITBIPS(20, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_amazfit_bips),
|
||||
LIVEVIEW(30, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_liveview),
|
||||
HPLUS(40, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_hplus),
|
||||
MAKIBESF68(41, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled, R.string.devicetype_makibes_f68),
|
||||
|
@ -36,6 +36,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.casiogb6900.CasioGB6
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.hplus.HPlusSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipLiteSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitgtr.AmazfitGTRSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitcor.AmazfitCorSupport;
|
||||
@ -149,6 +150,9 @@ public class DeviceSupportFactory {
|
||||
case AMAZFITBIP_LITE:
|
||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipLiteSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||
break;
|
||||
case AMAZFITBIPS:
|
||||
deviceSupport = new ServiceDeviceSupport(new AmazfitBipSSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||
break;
|
||||
case AMAZFITGTR:
|
||||
deviceSupport = new ServiceDeviceSupport(new AmazfitGTRSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||
break;
|
||||
|
@ -32,9 +32,10 @@ import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.TimeZone;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
|
||||
@ -55,6 +56,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSuppo
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BangleJSDeviceSupport.class);
|
||||
@ -81,7 +83,10 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
builder.notify(rxCharacteristic, true);
|
||||
|
||||
uartTx(builder, " \u0003"); // clear active line
|
||||
setTime(builder);
|
||||
|
||||
Prefs prefs = GBApplication.getPrefs();
|
||||
if (prefs.getBoolean("datetime_synconconnect", true))
|
||||
setTime(builder);
|
||||
//sendSettings(builder);
|
||||
|
||||
// get version
|
||||
@ -98,7 +103,7 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
private void uartTx(TransactionBuilder builder, String str) {
|
||||
LOG.info("UART TX: " + str);
|
||||
byte[] bytes;
|
||||
bytes = str.getBytes(StandardCharsets.UTF_8);
|
||||
bytes = str.getBytes(StandardCharsets.ISO_8859_1);
|
||||
for (int i=0;i<bytes.length;i+=20) {
|
||||
int l = bytes.length-i;
|
||||
if (l>20) l=20;
|
||||
@ -234,7 +239,15 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
|
||||
|
||||
void setTime(TransactionBuilder builder) {
|
||||
uartTx(builder, "\u0010setTime("+(System.currentTimeMillis()/1000)+");E.setTimeZone("+(TimeZone.getDefault().getRawOffset()/3600000)+");\n");
|
||||
long ts = System.currentTimeMillis();
|
||||
float tz = SimpleTimeZone.getDefault().getOffset(ts) / (1000 * 60 * 60.0f);
|
||||
// set time
|
||||
String cmd = "\u0010setTime("+(ts/1000)+");";
|
||||
// set timezone
|
||||
cmd += "E.setTimeZone("+tz+");";
|
||||
// write timezone to settings
|
||||
cmd += "(s=>{s&&(s.timezone="+tz+")&&require('Storage').write('setting.json',s);})(require('Storage').readJSON('setting.json',1))";
|
||||
uartTx(builder, cmd+"\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1928,7 +1928,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
buf.put((byte) 4);
|
||||
buf.putInt(weatherSpec.timestamp);
|
||||
buf.put((byte) (tz_offset_hours * 4));
|
||||
buf.putShort((short) 0);
|
||||
buf.putShort((short) -1);
|
||||
if (supportsConditionString) {
|
||||
buf.put(aqiString.getBytes());
|
||||
buf.put((byte) 0);
|
||||
|
@ -19,11 +19,14 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
public class AmazfitBipLiteFirmwareInfo extends HuamiFirmwareInfo {
|
||||
|
||||
@ -66,6 +69,15 @@ public class AmazfitBipLiteFirmwareInfo extends HuamiFirmwareInfo {
|
||||
if (searchString32BitAligned(bytes, "Amazfit Bip Lite")) {
|
||||
return HuamiFirmwareType.FIRMWARE;
|
||||
}
|
||||
GBDevice device = GBApplication.app().getDeviceManager().getSelectedDevice();
|
||||
if (device != null) {
|
||||
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
|
||||
if (prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_RELAX_FIRMWARE_CHECKS, false)) {
|
||||
if (searchString32BitAligned(bytes, "Amazfit Bip")) {
|
||||
return HuamiFirmwareType.FIRMWARE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HuamiFirmwareType.INVALID;
|
||||
}
|
||||
if (ArrayUtils.startsWith(bytes, WATCHFACE_HEADER)) {
|
||||
|
@ -0,0 +1,48 @@
|
||||
/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
|
||||
public class AmazfitBipSSupport extends AmazfitBipSupport {
|
||||
|
||||
@Override
|
||||
public byte getCryptFlags() {
|
||||
return (byte) 0x80;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotification(NotificationSpec notificationSpec) {
|
||||
super.sendNotificationNew(notificationSpec, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte getAuthFlags() {
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -77,7 +77,7 @@ public class AmazfitGTRFirmwareInfo extends HuamiFirmwareInfo {
|
||||
}
|
||||
return HuamiFirmwareType.INVALID;
|
||||
}
|
||||
if (ArrayUtils.startsWith(bytes, WATCHFACE_HEADER)) {
|
||||
if (ArrayUtils.startsWith(bytes, WATCHFACE_HEADER) || ArrayUtils.equals(bytes, WATCHFACE_HEADER, COMPRESSED_RES_HEADER_OFFSET_NEW) || ArrayUtils.equals(bytes, WATCHFACE_HEADER, COMPRESSED_RES_HEADER_OFFSET)) {
|
||||
return HuamiFirmwareType.WATCHFACE;
|
||||
}
|
||||
if (ArrayUtils.startsWith(bytes, NEWFT_HEADER)) {
|
||||
|
@ -26,6 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr.AmazfitGTRF
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.UpdateFirmwareOperationNew;
|
||||
|
||||
public class AmazfitGTRSupport extends AmazfitBipSupport {
|
||||
|
||||
@ -49,6 +50,11 @@ public class AmazfitGTRSupport extends AmazfitBipSupport {
|
||||
return new AmazfitGTRFWHelper(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateFirmwareOperationNew createUpdateFirmwareOperation(Uri uri) {
|
||||
return new UpdateFirmwareOperationNew(uri, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AmazfitGTRSupport setDisplayItems(TransactionBuilder builder) {
|
||||
// not supported yet
|
||||
|
@ -77,7 +77,7 @@ public class AmazfitGTSFirmwareInfo extends HuamiFirmwareInfo {
|
||||
}
|
||||
return HuamiFirmwareType.INVALID;
|
||||
}
|
||||
if (ArrayUtils.startsWith(bytes, WATCHFACE_HEADER)) {
|
||||
if (ArrayUtils.startsWith(bytes, WATCHFACE_HEADER) || ArrayUtils.equals(bytes, WATCHFACE_HEADER, COMPRESSED_RES_HEADER_OFFSET_NEW) || ArrayUtils.equals(bytes, WATCHFACE_HEADER, COMPRESSED_RES_HEADER_OFFSET)) {
|
||||
return HuamiFirmwareType.WATCHFACE;
|
||||
}
|
||||
if (ArrayUtils.startsWith(bytes, NEWFT_HEADER)) {
|
||||
|
@ -22,11 +22,11 @@ import android.net.Uri;
|
||||
import java.io.IOException;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr.AmazfitGTRFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgts.AmazfitGTSFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.UpdateFirmwareOperationNew;
|
||||
|
||||
public class AmazfitGTSSupport extends AmazfitBipSupport {
|
||||
|
||||
@ -51,6 +51,11 @@ public class AmazfitGTSSupport extends AmazfitBipSupport {
|
||||
return new AmazfitGTSFWHelper(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateFirmwareOperationNew createUpdateFirmwareOperation(Uri uri) {
|
||||
return new UpdateFirmwareOperationNew(uri, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AmazfitGTSSupport setDisplayItems(TransactionBuilder builder) {
|
||||
// not supported yet
|
||||
|
@ -89,6 +89,7 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
public static final String QHYBRID_COMMAND_SET_MENU_MESSAGE = "nodomain.freeyourgadget.gadgetbridge.Q_SET_MENU_MESSAGE";
|
||||
public static final String QHYBRID_COMMAND_SEND_MENU_ITEMS = "nodomain.freeyourgadget.gadgetbridge.Q_SEND_MENU_ITEMS";
|
||||
public static final String QHYBRID_COMMAND_SET_WIDGET_CONTENT = "nodomain.freeyourgadget.gadgetbridge.Q_SET_WIDGET_CONTENT";
|
||||
public static final String QHYBRID_COMMAND_SET_BACKGROUND_IMAGE = "nodomain.freeyourgadget.gadgetbridge.Q_SET_BACKGROUND_IMAGE";
|
||||
|
||||
private static final String QHYBRID_ACTION_SET_ACTIVITY_HAND = "nodomain.freeyourgadget.gadgetbridge.Q_SET_ACTIVITY_HAND";
|
||||
|
||||
@ -144,6 +145,7 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
commandFilter.addAction(QHYBRID_COMMAND_NOTIFICATION_CONFIG_CHANGED);
|
||||
commandFilter.addAction(QHYBRID_COMMAND_UPDATE_WIDGETS);
|
||||
commandFilter.addAction(QHYBRID_COMMAND_SEND_MENU_ITEMS);
|
||||
commandFilter.addAction(QHYBRID_COMMAND_SET_BACKGROUND_IMAGE);
|
||||
commandReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
@ -230,6 +232,11 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
watchAdapter.updateWidgets();
|
||||
break;
|
||||
}
|
||||
case QHYBRID_COMMAND_SET_BACKGROUND_IMAGE:{
|
||||
byte[] pixels = intent.getByteArrayExtra("EXTRA_PIXELS_ENCODED");
|
||||
watchAdapter.setBackgroundImage(pixels);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -534,6 +541,11 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
watchAdapter.onTestNewFunction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallApp(Uri uri) {
|
||||
watchAdapter.onInstallApp(uri);
|
||||
}
|
||||
|
||||
private void backupFile(DownloadFileRequest request) {
|
||||
try {
|
||||
File file = FileUtils.getExternalFile("qFiles/" + request.timeStamp);
|
||||
|
@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -63,6 +64,7 @@ public abstract class WatchAdapter {
|
||||
public abstract void syncNotificationSettings();
|
||||
public abstract void onTestNewFunction();
|
||||
public abstract void setTimezoneOffsetMinutes(short offset);
|
||||
public abstract void onInstallApp(Uri uri);
|
||||
|
||||
public abstract boolean supportsFindDevice();
|
||||
public abstract boolean supportsExtendedVibration();
|
||||
@ -130,4 +132,7 @@ public abstract class WatchAdapter {
|
||||
|
||||
public void onSendWeather(WeatherSpec weatherSpec) {
|
||||
}
|
||||
|
||||
public void setBackgroundImage(byte[] pixels) {
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -382,6 +383,11 @@ public class FossilWatchAdapter extends WatchAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallApp(Uri uri) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFindDevice() {
|
||||
return false;
|
||||
|
@ -8,14 +8,21 @@ import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@ -27,11 +34,15 @@ import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCallControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HRConfigActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HybridHRActivitySampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
||||
@ -42,9 +53,13 @@ import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityFileParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.TimeConfigItem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileDeleteRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayCallNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification.PlayTextNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest;
|
||||
@ -52,6 +67,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration.ConfigurationPutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFilePutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FirmwareFilePutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImage;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImageFactory;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.ImagesSetRequest;
|
||||
@ -66,9 +83,11 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.CustomWidgetElement;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.Widget;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.WidgetsPutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_PHONE_REQUEST;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.music.MusicControlRequest.MUSIC_WATCH_REQUEST;
|
||||
@ -138,30 +157,63 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
queueWrite(new ConfigurationPutRequest(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.VibrationStrengthConfigItem((byte) strength), this));
|
||||
}
|
||||
|
||||
private void loadNotificationConfigurations(){
|
||||
private void loadNotificationConfigurations() {
|
||||
this.notificationConfigurations = new NotificationHRConfiguration[]{
|
||||
new NotificationHRConfiguration("generic", 0),
|
||||
new NotificationHRConfiguration("call", new byte[]{(byte)0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}, 0)
|
||||
new NotificationHRConfiguration("call", new byte[]{(byte) 0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}, 0)
|
||||
};
|
||||
}
|
||||
|
||||
private void loadBackground(){
|
||||
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress()));
|
||||
boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false);
|
||||
if (forceWhiteBackground) {
|
||||
byte[] whiteGIF = new byte[]{
|
||||
0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x01, 0x00, 0x01, 0x00, (byte) 0x80, 0x01, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3B
|
||||
};
|
||||
private File getBackgroundFile() {
|
||||
return new File(getContext().getExternalFilesDir(null), "hr_background.bin");
|
||||
}
|
||||
|
||||
Bitmap backgroundBitmap = BitmapFactory.decodeByteArray(whiteGIF, 0, whiteGIF.length);
|
||||
//Bitmap backgroundBitmap = BitmapFactory.decodeFile("/sdcard/DCIM/Camera/IMG_20191129_200726.jpg");
|
||||
private void loadBackground() {
|
||||
this.backGroundImage = null;
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(getBackgroundFile());
|
||||
int count = fis.available();
|
||||
if (count != 14400) {
|
||||
throw new RuntimeException("wrong background file length");
|
||||
}
|
||||
byte[] file = new byte[14400];
|
||||
fis.read(file);
|
||||
fis.close();
|
||||
this.backGroundImage = AssetImageFactory.createAssetImage(file, 0, 0, 0);
|
||||
} catch (FileNotFoundException e) {
|
||||
SharedPreferences preferences = getDeviceSpecificPreferences();
|
||||
if (preferences.getBoolean("force_white_color_scheme", false)) {
|
||||
Bitmap whiteBitmap = Bitmap.createBitmap(239, 239, Bitmap.Config.ARGB_8888);
|
||||
new Canvas(whiteBitmap).drawColor(Color.WHITE);
|
||||
|
||||
try {
|
||||
this.backGroundImage = AssetImageFactory.createAssetImage(whiteBitmap, true, 0, 1, 0);
|
||||
} catch (IOException e2) {
|
||||
logger.error("Backgroundimage error", e2);
|
||||
}
|
||||
}
|
||||
} catch (IOException | RuntimeException e) {
|
||||
GB.log("error opening background file", GB.ERROR, e);
|
||||
GB.toast("error opening background file", Toast.LENGTH_LONG, GB.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundImage(byte[] pixels) {
|
||||
if (pixels == null) {
|
||||
getBackgroundFile().delete();
|
||||
loadBackground(); // recreates the white background in force-white mode, else backgroundImage=null
|
||||
} else {
|
||||
this.backGroundImage = AssetImageFactory.createAssetImage(pixels, 0, 0, 0);
|
||||
try {
|
||||
this.backGroundImage = AssetImageFactory.createAssetImage(backgroundBitmap, false, 0, 0, 0);
|
||||
FileOutputStream fos = new FileOutputStream(getBackgroundFile(), false);
|
||||
fos.write(pixels);
|
||||
} catch (IOException e) {
|
||||
logger.error("Backgroundimage error", e);
|
||||
GB.log("error saving background", GB.ERROR, e);
|
||||
GB.toast("error persistent saving background", Toast.LENGTH_LONG, GB.ERROR);
|
||||
}
|
||||
}
|
||||
renderWidgets();
|
||||
}
|
||||
|
||||
private void loadWidgets() {
|
||||
@ -184,19 +236,22 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
positionMap.put("bottom", 180);
|
||||
positionMap.put("left", 270);
|
||||
|
||||
while(keyIterator.hasNext()){
|
||||
while (keyIterator.hasNext()) {
|
||||
String position = keyIterator.next();
|
||||
String identifier = widgetConfig.getString(position);
|
||||
Widget.WidgetType type = Widget.WidgetType.fromJsonIdentifier(identifier);
|
||||
|
||||
Widget widget = null;
|
||||
if(type != null) {
|
||||
if (type != null) {
|
||||
widget = new Widget(type, positionMap.get(position), 63, fontColor);
|
||||
}else{
|
||||
} else {
|
||||
identifier = identifier.substring(7);
|
||||
for(int i = 0; i < customWidgets.length(); i++){
|
||||
for (int i = 0; i < customWidgets.length(); i++) {
|
||||
JSONObject customWidget = customWidgets.getJSONObject(i);
|
||||
if(customWidget.getString("name").equals(identifier)){
|
||||
if (customWidget.getString("name").equals(identifier)) {
|
||||
boolean drawCircle = false;
|
||||
if (customWidget.has("drawCircle"))
|
||||
drawCircle = customWidget.getBoolean("drawCircle");
|
||||
CustomWidget newWidget = new CustomWidget(
|
||||
customWidget.getString("name"),
|
||||
positionMap.get(position),
|
||||
@ -226,7 +281,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
if(widget == null) continue;
|
||||
if (widget == null) continue;
|
||||
this.widgets.add(widget);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
@ -236,11 +291,11 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
uploadWidgets();
|
||||
}
|
||||
|
||||
private void uploadWidgets(){
|
||||
private void uploadWidgets() {
|
||||
negotiateSymmetricKey();
|
||||
ArrayList<Widget> systemWidgets = new ArrayList<>(widgets.size());
|
||||
for(Widget widget : this.widgets){
|
||||
if(!(widget instanceof CustomWidget)) systemWidgets.add(widget);
|
||||
for (Widget widget : this.widgets) {
|
||||
if (!(widget instanceof CustomWidget)) systemWidgets.add(widget);
|
||||
}
|
||||
queueWrite(new WidgetsPutRequest(systemWidgets.toArray(new Widget[0]), this));
|
||||
}
|
||||
@ -248,48 +303,68 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
private void renderWidgets() {
|
||||
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDeviceSupport().getDevice().getAddress()));
|
||||
boolean forceWhiteBackground = prefs.getBoolean("force_white_color_scheme", false);
|
||||
boolean drawCircles = prefs.getBoolean("widget_draw_circles", false);
|
||||
|
||||
Bitmap circleBitmap = null;
|
||||
if (drawCircles) {
|
||||
circleBitmap = Bitmap.createBitmap(76, 76, Bitmap.Config.ARGB_8888);
|
||||
Canvas circleCanvas = new Canvas(circleBitmap);
|
||||
Paint circlePaint = new Paint();
|
||||
circlePaint.setAntiAlias(true);
|
||||
circlePaint.setColor(forceWhiteBackground ? Color.WHITE : Color.BLACK);
|
||||
circlePaint.setStyle(Paint.Style.FILL);
|
||||
circlePaint.setStrokeWidth(3);
|
||||
circleCanvas.drawCircle(38, 38, 35, circlePaint);
|
||||
|
||||
circlePaint.setColor(forceWhiteBackground ? Color.BLACK : Color.WHITE);
|
||||
circlePaint.setStyle(Paint.Style.STROKE);
|
||||
circlePaint.setStrokeWidth(3);
|
||||
circleCanvas.drawCircle(38, 38, 35, circlePaint);
|
||||
}
|
||||
|
||||
try {
|
||||
ArrayList<AssetImage> widgetImages = new ArrayList<>();
|
||||
|
||||
if(this.backGroundImage != null){
|
||||
if (this.backGroundImage != null) {
|
||||
widgetImages.add(this.backGroundImage);
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < this.widgets.size(); i++) {
|
||||
Widget w = widgets.get(i);
|
||||
if(!(w instanceof CustomWidget)) continue;
|
||||
if (!(w instanceof CustomWidget)) {
|
||||
if (drawCircles) {
|
||||
widgetImages.add(AssetImageFactory.createAssetImage(
|
||||
circleBitmap,
|
||||
true,
|
||||
w.getAngle(),
|
||||
w.getDistance(),
|
||||
1
|
||||
));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
;
|
||||
CustomWidget widget = (CustomWidget) w;
|
||||
|
||||
Bitmap widgetBitmap = Bitmap.createBitmap(76, 76, Bitmap.Config.ARGB_8888);
|
||||
|
||||
Canvas widgetCanvas = new Canvas(widgetBitmap);
|
||||
|
||||
boolean backgroundDrawn = false;
|
||||
|
||||
Paint circlePaint = new Paint();
|
||||
if(!backgroundDrawn){
|
||||
circlePaint.setColor(forceWhiteBackground ? Color.WHITE : Color.BLACK);
|
||||
circlePaint.setStyle(Paint.Style.FILL);
|
||||
circlePaint.setStrokeWidth(3);
|
||||
widgetCanvas.drawCircle(38, 38, 37, circlePaint);
|
||||
|
||||
circlePaint.setColor(forceWhiteBackground ? Color.BLACK : Color.WHITE);
|
||||
circlePaint.setStyle(Paint.Style.STROKE);
|
||||
circlePaint.setStrokeWidth(3);
|
||||
widgetCanvas.drawCircle(38, 38, 37, circlePaint);
|
||||
if (drawCircles) {
|
||||
widgetCanvas.drawBitmap(circleBitmap, 0, 0, null);
|
||||
}
|
||||
|
||||
for (CustomWidgetElement element : widget.getElements()) {
|
||||
if (element.getWidgetElementType() == CustomWidgetElement.WidgetElementType.TYPE_BACKGROUND) {
|
||||
File imageFile = new File(element.getValue());
|
||||
|
||||
if(!imageFile.exists() || !imageFile.isFile()){
|
||||
if (!imageFile.exists() || !imageFile.isFile()) {
|
||||
logger.debug("Image file " + element.getValue() + " not found");
|
||||
continue;
|
||||
}
|
||||
Bitmap imageBitmap = BitmapFactory.decodeFile(element.getValue());
|
||||
if(imageBitmap == null){
|
||||
if (imageBitmap == null) {
|
||||
logger.debug("image file " + element.getValue() + " could not be decoded");
|
||||
continue;
|
||||
}
|
||||
@ -300,7 +375,6 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
0,
|
||||
0,
|
||||
null);
|
||||
backgroundDrawn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -315,7 +389,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
textPaint.setTextAlign(Paint.Align.CENTER);
|
||||
|
||||
widgetCanvas.drawText(element.getValue(), element.getX(), element.getY() - (textPaint.descent() + textPaint.ascent()) / 2f, textPaint);
|
||||
}else if(element.getWidgetElementType() == CustomWidgetElement.WidgetElementType.TYPE_IMAGE) {
|
||||
} else if (element.getWidgetElementType() == CustomWidgetElement.WidgetElementType.TYPE_IMAGE) {
|
||||
Bitmap imageBitmap = BitmapFactory.decodeFile(element.getValue());
|
||||
|
||||
widgetCanvas.drawBitmap(imageBitmap, element.getX() - imageBitmap.getWidth() / 2f, element.getY() - imageBitmap.getHeight() / 2f, null);
|
||||
@ -330,15 +404,14 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
AssetImage[] images = widgetImages.toArray(new AssetImage[0]);
|
||||
|
||||
// queueWrite(new FileDeleteRequest((short) 0x0700));
|
||||
queueWrite(new AssetFilePutRequest(
|
||||
images,
|
||||
(byte) 0x00,
|
||||
this
|
||||
));
|
||||
|
||||
// queueWrite(new FileDeleteRequest((short) 0x0503));
|
||||
queueWrite(new ImagesSetRequest(
|
||||
images,
|
||||
@ -353,8 +426,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
public void setWidgetContent(String widgetID, String content, boolean renderOnWatch) {
|
||||
boolean update = false;
|
||||
for (Widget widget : this.widgets) {
|
||||
if(!(widget instanceof CustomWidget)) continue;
|
||||
if(((CustomWidget) widget).updateElementValue(widgetID, content)) update = true;
|
||||
if (!(widget instanceof CustomWidget)) continue;
|
||||
if (((CustomWidget) widget).updateElementValue(widgetID, content)) update = true;
|
||||
}
|
||||
|
||||
if (renderOnWatch && update) renderWidgets();
|
||||
@ -401,7 +474,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
musicSpec.track,
|
||||
this
|
||||
));
|
||||
}catch (BufferOverflowException e){
|
||||
} catch (BufferOverflowException e) {
|
||||
GB.log("musicInfo: " + musicSpec, GB.ERROR, e);
|
||||
}
|
||||
}
|
||||
@ -424,6 +497,66 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
@Override
|
||||
public void onFetchActivityData() {
|
||||
syncSettings();
|
||||
|
||||
queueWrite(new VerifyPrivateKeyRequest(this.getSecretKey(), this));
|
||||
queueWrite(new FileLookupRequest((byte) 0x01, this){
|
||||
@Override
|
||||
public void handleFileLookup(final short fileHandle) {
|
||||
queueWrite(new FileEncryptedGetRequest(fileHandle, FossilHRWatchAdapter.this) {
|
||||
@Override
|
||||
public void handleFileData(byte[] fileData) {
|
||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||
ActivityFileParser parser = new ActivityFileParser();
|
||||
ArrayList<ActivityEntry> entries = parser.parseFile(fileData);
|
||||
HybridHRActivitySampleProvider provider = new HybridHRActivitySampleProvider(getDeviceSupport().getDevice(), dbHandler.getDaoSession());
|
||||
|
||||
HybridHRActivitySample[] samples = new HybridHRActivitySample[entries.size()];
|
||||
|
||||
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
|
||||
Long deviceId = DBHelper.getDevice(getDeviceSupport(). getDevice(), dbHandler.getDaoSession()).getId();
|
||||
for(int i = 0; i < entries.size(); i++){
|
||||
samples[i] = entries.get(i).toDAOActivitySample(userId, deviceId);
|
||||
}
|
||||
|
||||
provider.addGBActivitySamples(samples);
|
||||
|
||||
writeFile(String.valueOf(System.currentTimeMillis()), fileData);
|
||||
queueWrite(new FileDeleteRequest(fileHandle));
|
||||
GB.toast("synced activity data", Toast.LENGTH_SHORT, GB.INFO);
|
||||
} catch (Exception ex) {
|
||||
GB.toast(getContext(), "Error saving steps data: " + ex.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR);
|
||||
GB.updateTransferNotification(null, "Data transfer failed", false, 0, getContext());
|
||||
}
|
||||
getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFileLookupError(FILE_LOOKUP_ERROR error) {
|
||||
if(error == FILE_LOOKUP_ERROR.FILE_EMPTY){
|
||||
GB.toast("activity file empty yet", Toast.LENGTH_LONG, GB.ERROR);
|
||||
}else{
|
||||
throw new RuntimeException("strange lookup stuff");
|
||||
}
|
||||
getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void writeFile(String fileName, byte[] value){
|
||||
File activityDir = new File(getContext().getExternalFilesDir(null), "activity_hr");
|
||||
activityDir.mkdir();
|
||||
File f = new File(activityDir, fileName);
|
||||
try {
|
||||
f.createNewFile();
|
||||
FileOutputStream fos = new FileOutputStream(f);
|
||||
fos.write(value);
|
||||
fos.close();
|
||||
GB.toast("saved file data", Toast.LENGTH_SHORT, GB.INFO);
|
||||
} catch (IOException e) {
|
||||
GB.log("file error", GB.ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncSettings() {
|
||||
@ -441,14 +574,14 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
String senderOrTitle = StringUtils.getFirstOf(notificationSpec.sender, notificationSpec.title);
|
||||
|
||||
try {
|
||||
for (NotificationHRConfiguration configuration : this.notificationConfigurations){
|
||||
if(configuration.getPackageName().equals(notificationSpec.sourceAppId)){
|
||||
for (NotificationHRConfiguration configuration : this.notificationConfigurations) {
|
||||
if (configuration.getPackageName().equals(notificationSpec.sourceAppId)) {
|
||||
queueWrite(new PlayTextNotificationRequest(notificationSpec.sourceAppId, senderOrTitle, notificationSpec.body, this));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
queueWrite(new PlayTextNotificationRequest("generic", senderOrTitle, notificationSpec.body, this));
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
@ -456,14 +589,14 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
|
||||
@Override
|
||||
public void onFindDevice(boolean start) {
|
||||
if(start){
|
||||
if (start) {
|
||||
new TransactionBuilder("vibrate find")
|
||||
.write(
|
||||
getDeviceSupport().getCharacteristic(UUID.fromString("3dda0005-957f-7d4a-34a6-74696673696d")),
|
||||
new byte[]{(byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0x75, (byte) 0x00, (byte) 0x00}
|
||||
)
|
||||
)
|
||||
.queue(getDeviceSupport().getQueue());
|
||||
}else{
|
||||
} else {
|
||||
new TransactionBuilder("vibrate find")
|
||||
.write(
|
||||
getDeviceSupport().getCharacteristic(UUID.fromString("3dda0005-957f-7d4a-34a6-74696673696d")),
|
||||
@ -606,35 +739,48 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// this was used to enumerate the weather icons :)
|
||||
/*
|
||||
static int i = 0;
|
||||
|
||||
@Override
|
||||
public void onTestNewFunction() {
|
||||
long ts = System.currentTimeMillis();
|
||||
ts /= 1000;
|
||||
/*queueWrite(new ActivityFilesGetRequest(this){
|
||||
@Override
|
||||
public void handleFileData(byte[] fileData) {
|
||||
super.handleFileData(fileData);
|
||||
File activityDir = new File(getContext().getExternalFilesDir(null), "activity_hr");
|
||||
activityDir.mkdir();
|
||||
File f = new File(activityDir, String.valueOf(System.currentTimeMillis()));
|
||||
try {
|
||||
f.createNewFile();
|
||||
FileOutputStream fos = new FileOutputStream(f);
|
||||
fos.write(fileData);
|
||||
fos.close();
|
||||
GB.toast("saved file data", Toast.LENGTH_SHORT, GB.INFO);
|
||||
} catch (IOException e) {
|
||||
GB.log("activity file error", GB.ERROR, e);
|
||||
}
|
||||
queueWrite(new FileDeleteRequest((short) 0x0101));
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallApp(Uri uri) {
|
||||
UriHelper uriHelper = null;
|
||||
try {
|
||||
JSONObject responseObject = new JSONObject()
|
||||
.put("res", new JSONObject()
|
||||
.put("id", 0) // seems the id does not matter?
|
||||
.put("set", new JSONObject()
|
||||
.put("weatherInfo", new JSONObject()
|
||||
.put("alive", ts + 60 * 60)
|
||||
.put("unit", "c")
|
||||
.put("temp", i)
|
||||
.put("cond_id", i++)
|
||||
)
|
||||
));
|
||||
|
||||
queueWrite(new JsonPutRequest(responseObject, this));
|
||||
|
||||
} catch (JSONException e) {
|
||||
logger.error(" JSON exception: ", e);
|
||||
uriHelper = UriHelper.get(uri, getContext());
|
||||
} catch (IOException e) {
|
||||
GB.toast(getContext(), "Could not open firmare: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
if (uriHelper != null) {
|
||||
try (InputStream in = new BufferedInputStream(uriHelper.openInputStream())) {
|
||||
byte[] firmwareBytes = FileUtils.readAll(in, 1024 * 2024); // 2MB
|
||||
queueWrite(new FirmwareFilePutRequest(firmwareBytes, this));
|
||||
} catch (Exception e) {
|
||||
GB.toast(getContext(), "Firmware cannot be installed: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public byte[] getSecretKey() {
|
||||
byte[] authKeyBytes = new byte[16];
|
||||
|
||||
@ -704,6 +850,14 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
break;
|
||||
case DeviceSettingsPreferenceConst.PREF_VIBRATION_STRENGH_PERCENTAGE:
|
||||
setVibrationStrength();
|
||||
break;
|
||||
case "force_white_color_scheme":
|
||||
loadBackground();
|
||||
// not break here
|
||||
case "widget_draw_circles": {
|
||||
renderWidgets();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,9 +880,9 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
||||
|
||||
byte requestType = value[1];
|
||||
|
||||
if(requestType == (byte) 0x04){
|
||||
if (requestType == (byte) 0x04) {
|
||||
handleCallRequest(value);
|
||||
}else if (requestType == (byte) 0x05) {
|
||||
} else if (requestType == (byte) 0x05) {
|
||||
handleMusicRequest(value);
|
||||
} else if (requestType == (byte) 0x01) {
|
||||
int eventId = value[2];
|
||||
|
@ -19,7 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.mis
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import android.net.Uri;
|
||||
import android.util.SparseArray;
|
||||
import android.widget.Toast;
|
||||
|
||||
@ -49,6 +49,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ActivityPointGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.BatteryLevelRequest;
|
||||
@ -66,7 +67,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.mis
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.OTAEraseRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ReleaseHandsControlRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.RequestHandControlRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetCurrentStepCountRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetStepGoalRequest;
|
||||
@ -418,6 +418,11 @@ public class MisfitWatchAdapter extends WatchAdapter {
|
||||
GB.toast("old firmware does't support timezones", Toast.LENGTH_LONG, GB.ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallApp(Uri uri) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFindDevice() {
|
||||
return supportsExtendedVibration();
|
||||
|
@ -0,0 +1,65 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
|
||||
public class ActivityEntry {
|
||||
public int id;
|
||||
public int heartRate;
|
||||
public int variability, maxVariability;
|
||||
public int calories;
|
||||
public int stepCount;
|
||||
public boolean isActive;
|
||||
|
||||
public int timestamp;
|
||||
|
||||
public int heartRateQuality;
|
||||
|
||||
public WEARING_STATE wearingState;
|
||||
|
||||
public HybridHRActivitySample toDAOActivitySample(long userId, long deviceId) {
|
||||
HybridHRActivitySample sample = new HybridHRActivitySample(
|
||||
timestamp,
|
||||
deviceId,
|
||||
userId,
|
||||
stepCount,
|
||||
calories,
|
||||
variability,
|
||||
maxVariability,
|
||||
heartRateQuality,
|
||||
isActive,
|
||||
wearingState.value,
|
||||
heartRate
|
||||
);
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
public enum WEARING_STATE{
|
||||
WEARING((byte) 0, ActivityKind.TYPE_NOT_MEASURED),
|
||||
NOT_WEARING((byte) 1, ActivityKind.TYPE_NOT_WORN),
|
||||
UNKNOWN((byte) 2, ActivityKind.TYPE_UNKNOWN);
|
||||
|
||||
byte value;
|
||||
int activityKind;
|
||||
|
||||
WEARING_STATE(byte value, int activityKind){
|
||||
this.value = value;
|
||||
this.activityKind = activityKind;
|
||||
}
|
||||
|
||||
public int getActivityKind() {
|
||||
return activityKind;
|
||||
}
|
||||
|
||||
static public WEARING_STATE fromValue(byte value){
|
||||
switch (value){
|
||||
case 0: return WEARING_STATE.WEARING;
|
||||
case 1: return WEARING_STATE.NOT_WEARING;
|
||||
case 2: return WEARING_STATE.UNKNOWN;
|
||||
default: throw new RuntimeException("value " + value + " not valid state value");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ActivityFileParser {
|
||||
// state flags;
|
||||
int heartRateQuality;
|
||||
ActivityEntry.WEARING_STATE wearingState = ActivityEntry.WEARING_STATE.UNKNOWN;
|
||||
int currentTimestamp = -1;
|
||||
ActivityEntry currentSample = null;
|
||||
int currentId = 1;
|
||||
|
||||
public ArrayList<ActivityEntry> parseFile(byte[] file) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(file);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// read file version
|
||||
short version = buffer.getShort(2);
|
||||
if (version != 22) throw new RuntimeException("File version " + version + ", 16 required");
|
||||
|
||||
int startTime = buffer.getInt(8);
|
||||
short timeOffsetMinutes = buffer.getShort(12);
|
||||
|
||||
short fileId = buffer.getShort(16);
|
||||
|
||||
buffer.position(20);
|
||||
|
||||
ArrayList<ActivityEntry> samples = new ArrayList<>();
|
||||
finishCurrentPacket(samples);
|
||||
|
||||
while (buffer.position() < buffer.capacity() - 4) {
|
||||
byte next = buffer.get();
|
||||
|
||||
if (paraseFlag(next, buffer, samples)) continue;
|
||||
|
||||
if(currentSample != null) {
|
||||
parseVariabilityBytes(next, buffer.get());
|
||||
|
||||
int heartRate = buffer.get() & 0xFF;
|
||||
int calories = buffer.get() & 0xFF;
|
||||
boolean isActive = (calories & 0x40) == 0x40; // upper two bits
|
||||
calories &= 0x3F; // delete upper two bits
|
||||
|
||||
currentSample.heartRate = heartRate;
|
||||
currentSample.calories = calories;
|
||||
currentSample.isActive = isActive;
|
||||
finishCurrentPacket(samples);
|
||||
}
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
private boolean paraseFlag(byte flag, ByteBuffer buffer, ArrayList<ActivityEntry> samples) {
|
||||
switch (flag) {
|
||||
case (byte) 0xCA:
|
||||
case (byte) 0xCB:
|
||||
case (byte) 0xCC:
|
||||
case (byte) 0xCD:
|
||||
buffer.get();
|
||||
break;
|
||||
case (byte) 0xCE:
|
||||
byte arg = buffer.get();
|
||||
byte wearBits = (byte)((arg & 0b00011000) >> 3);
|
||||
if(wearBits == 0) this.wearingState = ActivityEntry.WEARING_STATE.NOT_WEARING;
|
||||
else if(wearBits == 1) this.wearingState = ActivityEntry.WEARING_STATE.WEARING;
|
||||
else this.wearingState = ActivityEntry.WEARING_STATE.UNKNOWN;
|
||||
|
||||
byte heartRateQualityBits = (byte)((arg & 0b11100000) >> 5);
|
||||
this.heartRateQuality = heartRateQualityBits;
|
||||
break;
|
||||
case (byte) 0xCF:
|
||||
case (byte) 0xDE:
|
||||
case (byte) 0xDF:
|
||||
case (byte) 0xE1:
|
||||
buffer.get();
|
||||
break;
|
||||
case (byte) 0xE2:
|
||||
byte type = buffer.get();
|
||||
int timestamp = buffer.getInt();
|
||||
short duration = buffer.getShort();
|
||||
short minutesOffset = buffer.getShort();
|
||||
if (type == 0x04) {
|
||||
this.currentTimestamp = timestamp;
|
||||
}
|
||||
break;
|
||||
case (byte) 0xDD:
|
||||
case (byte) 0xFD:
|
||||
buffer.get();
|
||||
break;
|
||||
case (byte) 0xFE:
|
||||
byte arg2 = buffer.get();
|
||||
if(arg2 == (byte) 0xFE) {
|
||||
// this.currentSample = new ActivitySample();
|
||||
// this.currentSample.id = currentId++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseVariabilityBytes(byte lower, byte higher){
|
||||
if((lower & 0b0000001) == 0b0000001){
|
||||
currentSample.maxVariability = (higher & 0b00000011) * 25 + 1;
|
||||
currentSample.stepCount = lower & 0b1110;
|
||||
if((lower & 0b10000000) == 0b10000000){
|
||||
int factor = (lower >> 4) & 0b111;
|
||||
currentSample.variability = 512 + factor * 64 + (higher >> 2 & 0b111111);
|
||||
currentSample.stepCount = lower & 0b1110;
|
||||
}else {
|
||||
currentSample.variability = lower & 0b01110000;
|
||||
currentSample.variability <<= 2;
|
||||
currentSample.variability |= (higher >> 2) & 0b111111;
|
||||
}
|
||||
}else{
|
||||
currentSample.variability = (int) higher * (int) higher * 64;
|
||||
currentSample.maxVariability = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
private void finishCurrentPacket(ArrayList<ActivityEntry> samples) {
|
||||
if (currentSample != null) {
|
||||
currentSample.timestamp = currentTimestamp;
|
||||
currentSample.heartRateQuality = this.heartRateQuality;
|
||||
currentSample.wearingState = wearingState;
|
||||
currentTimestamp += 60;
|
||||
samples.add(currentSample);
|
||||
currentSample = null;
|
||||
}
|
||||
this.currentSample = new ActivityEntry();
|
||||
this.currentSample.id = currentId++;
|
||||
}
|
||||
}
|
@ -16,12 +16,15 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm;
|
||||
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FileLookupAndGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class AlarmsGetRequest extends FileLookupAndGetRequest {
|
||||
public AlarmsGetRequest(FossilWatchAdapter adapter) {
|
||||
@ -59,4 +62,13 @@ public class AlarmsGetRequest extends FileLookupAndGetRequest {
|
||||
alarms2[i] = Alarm.fromBytes(alarms[i].getData());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFileLookupError(FILE_LOOKUP_ERROR error) {
|
||||
if(error == FILE_LOOKUP_ERROR.FILE_EMPTY){
|
||||
GB.toast("alarm file empty yet", Toast.LENGTH_LONG, GB.ERROR);
|
||||
}else{
|
||||
throw new RuntimeException("strange lookup stuff");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,17 +20,14 @@ import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.ResultCode;
|
||||
|
||||
public class FileLookupRequest extends FossilRequest {
|
||||
public abstract class FileLookupRequest extends FossilRequest {
|
||||
private short handle = -1;
|
||||
private byte fileType;
|
||||
|
||||
@ -91,6 +88,11 @@ public class FileLookupRequest extends FossilRequest {
|
||||
// throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
|
||||
}
|
||||
log("file size: " + size);
|
||||
if(size == 0){
|
||||
this.handleFileLookupError(FILE_LOOKUP_ERROR.FILE_EMPTY);
|
||||
finished = true;
|
||||
return;
|
||||
}
|
||||
fileBuffer = ByteBuffer.allocate(size);
|
||||
}else if((first & 0x0F) == 8){
|
||||
this.finished = true;
|
||||
@ -122,7 +124,9 @@ public class FileLookupRequest extends FossilRequest {
|
||||
}
|
||||
}
|
||||
|
||||
public void handleFileLookup(short fileHandle){}
|
||||
public abstract void handleFileLookup(short fileHandle);
|
||||
|
||||
public abstract void handleFileLookupError(FILE_LOOKUP_ERROR error);
|
||||
|
||||
@Override
|
||||
public UUID getRequestUUID() {
|
||||
@ -138,4 +142,8 @@ public class FileLookupRequest extends FossilRequest {
|
||||
public int getPayloadLength() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public enum FILE_LOOKUP_ERROR{
|
||||
FILE_EMPTY;
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ import java.nio.ByteOrder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
|
||||
public class PlayCallNotificationRequest extends PlayNotificationRequest {
|
||||
private final static int MESSAGE_ID_CALL = 1;
|
||||
|
||||
public PlayCallNotificationRequest(String number, boolean callStart, FossilWatchAdapter adapter) {
|
||||
super(callStart ? 1 : 7, callStart ? 8 : 2,
|
||||
ByteBuffer.wrap(new byte[]{(byte) 0x80, (byte) 0x00, (byte) 0x59, (byte) 0xB7}).order(ByteOrder.LITTLE_ENDIAN).getInt(),
|
||||
number, "Incoming Call", adapter);
|
||||
number, "Incoming Call", MESSAGE_ID_CALL, adapter);
|
||||
}
|
||||
}
|
||||
|
@ -28,24 +28,28 @@ import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
|
||||
public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
public PlayNotificationRequest(int notificationType, int flags, String packageName, FossilWatchAdapter adapter) {
|
||||
super((short) 0x0900, createFile(notificationType, flags, packageName, packageName, packageName), adapter);
|
||||
super((short) 0x0900, createFile(notificationType, flags, packageName, packageName, packageName, getCurrentMessageId()), adapter);
|
||||
}
|
||||
|
||||
public PlayNotificationRequest(int notificationType, int flags, String packageName, String sender, String message, FossilWatchAdapter adapter) {
|
||||
super((short) 0x0900, createFile(notificationType, flags, packageName, sender, message), adapter);
|
||||
super((short) 0x0900, createFile(notificationType, flags, packageName, sender, message, getCurrentMessageId()), adapter);
|
||||
}
|
||||
|
||||
public PlayNotificationRequest(int notificationType, int flags, int packageCRC, String sender, String message, FossilWatchAdapter adapter) {
|
||||
super((short) 0x0900, createFile(notificationType, flags, "whatever", sender, message, packageCRC), adapter);
|
||||
public PlayNotificationRequest(int notificationType, int flags, int packageCRC, String sender, String message, int messageId, FossilWatchAdapter adapter) {
|
||||
super((short) 0x0900, createFile(notificationType, flags, "whatever", sender, message, packageCRC, messageId), adapter);
|
||||
}
|
||||
|
||||
private static byte[] createFile(int notificationType, int flags, String packageName, String sender, String message){
|
||||
private static int getCurrentMessageId(){
|
||||
return (int) System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private static byte[] createFile(int notificationType, int flags, String packageName, String sender, String message, int messageId){
|
||||
CRC32 crc = new CRC32();
|
||||
crc.update(packageName.getBytes());
|
||||
return createFile(notificationType, flags, packageName, sender, message, (int)crc.getValue());
|
||||
return createFile(notificationType, flags, packageName, sender, message, (int)crc.getValue(), messageId);
|
||||
}
|
||||
|
||||
private static byte[] createFile(int notificationType, int flags, String title, String sender, String message, int packageCrc) {
|
||||
private static byte[] createFile(int notificationType, int flags, String title, String sender, String message, int packageCrc, int messageId) {
|
||||
byte lengthBufferLength = (byte) 10;
|
||||
byte uidLength = (byte) 4;
|
||||
byte appBundleCRCLength = (byte) 4;
|
||||
@ -59,7 +63,7 @@ public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
String nullTerminatedMessage = StringUtils.terminateNull(message);
|
||||
byte[] messageBytes = nullTerminatedMessage.getBytes(charsetUTF8);
|
||||
if (messageBytes.length > 490) {
|
||||
messageBytes = Arrays.copyOf(messageBytes, 490);
|
||||
messageBytes = Arrays.copyOf(messageBytes, 475);
|
||||
}
|
||||
short mainBufferLength = (short) (lengthBufferLength + uidLength + appBundleCRCLength + titleBytes.length + senderBytes.length + messageBytes.length);
|
||||
|
||||
@ -77,7 +81,7 @@ public abstract class PlayNotificationRequest extends FilePutRequest {
|
||||
mainBuffer.put((byte) senderBytes.length);
|
||||
mainBuffer.put((byte) messageBytes.length);
|
||||
|
||||
mainBuffer.putInt(0); // messageId
|
||||
mainBuffer.putInt(messageId);
|
||||
mainBuffer.putInt(packageCrc);
|
||||
mainBuffer.put(titleBytes);
|
||||
mainBuffer.put(senderBytes);
|
||||
|
@ -0,0 +1,15 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.activity;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedGetRequest;
|
||||
|
||||
public class ActivityFilesGetRequest extends FileEncryptedGetRequest {
|
||||
public ActivityFilesGetRequest(FossilHRWatchAdapter adapter) {
|
||||
super((short) 0x0101, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFileData(byte[] fileData) {
|
||||
assert Boolean.TRUE;
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.configuration;
|
||||
|
||||
import android.widget.Toast;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
||||
@ -54,4 +56,13 @@ public class ConfigurationGetRequest extends FileEncryptedLookupAndGetRequest {
|
||||
|
||||
device.sendDeviceUpdateIntent(getAdapter().getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFileLookupError(FILE_LOOKUP_ERROR error) {
|
||||
if(error == FILE_LOOKUP_ERROR.FILE_EMPTY){
|
||||
GB.toast("config file empty", Toast.LENGTH_LONG, GB.ERROR);
|
||||
}else{
|
||||
throw new RuntimeException("strange lookup stuff");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,15 +18,10 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fo
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedPutRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.ConfigItem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedPutRequest;
|
||||
|
||||
public class ConfigurationPutRequest extends FileEncryptedPutRequest {
|
||||
public ConfigurationPutRequest(ConfigItem item, FossilHRWatchAdapter adapter) {
|
||||
|
@ -12,16 +12,16 @@ public class AssetFilePutRequest extends FilePutRequest {
|
||||
public AssetFilePutRequest(AssetFile[] files, byte subHandle, FossilWatchAdapter adapter) throws IOException {
|
||||
super((short) (0x0700 | subHandle), prepareFileData(files), adapter);
|
||||
}
|
||||
public AssetFilePutRequest(AssetFile file, byte subHandle, FossilWatchAdapter adapter) throws IOException {
|
||||
public AssetFilePutRequest(AssetFile file, byte subHandle, FossilWatchAdapter adapter) {
|
||||
super((short) (0x0700 | subHandle), prepareFileData(file), adapter);
|
||||
}
|
||||
|
||||
private static byte[] prepareFileData(AssetFile[] files) throws IOException {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
|
||||
for(int i = 0; i < files.length; i++){
|
||||
for (AssetFile file : files) {
|
||||
stream.write(
|
||||
prepareFileData(files[i])
|
||||
prepareFileData(file)
|
||||
);
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ public class AssetFilePutRequest extends FilePutRequest {
|
||||
}
|
||||
|
||||
private static byte[] prepareFileData(AssetFile file){
|
||||
int size = file.getFileName().length() + file.getFileData().length + 1 /**null byte **/;
|
||||
int size = file.getFileName().length() + file.getFileData().length + 1; // null byte
|
||||
ByteBuffer buffer = ByteBuffer.allocate(size + 2);
|
||||
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
@ -23,7 +23,6 @@ import java.nio.ByteOrder;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
@ -34,11 +33,10 @@ import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.CRC32C;
|
||||
|
||||
public abstract class FileEncryptedGetRequest extends FossilRequest {
|
||||
private short handle;
|
||||
@ -50,6 +48,10 @@ public abstract class FileEncryptedGetRequest extends FossilRequest {
|
||||
|
||||
private boolean finished = false;
|
||||
|
||||
private Cipher cipher;
|
||||
private SecretKeySpec keySpec;
|
||||
private byte[] iv;
|
||||
|
||||
public FileEncryptedGetRequest(short handle, FossilHRWatchAdapter adapter) {
|
||||
this.handle = handle;
|
||||
this.adapter = adapter;
|
||||
@ -62,12 +64,42 @@ public abstract class FileEncryptedGetRequest extends FossilRequest {
|
||||
.array();
|
||||
}
|
||||
|
||||
private void initDecryption() {
|
||||
try {
|
||||
cipher = Cipher.getInstance("AES/CTR/NoPadding");
|
||||
keySpec = new SecretKeySpec(this.adapter.getSecretKey(), "AES");
|
||||
|
||||
|
||||
iv = new byte[16];
|
||||
|
||||
|
||||
byte[] phoneRandomNumber = adapter.getPhoneRandomNumber();
|
||||
byte[] watchRandomNumber = adapter.getWatchRandomNumber();
|
||||
|
||||
System.arraycopy(phoneRandomNumber, 0, iv, 2, 6);
|
||||
System.arraycopy(watchRandomNumber, 0, iv, 9, 7);
|
||||
|
||||
iv[7]++;
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public FossilWatchAdapter getAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private void incrementIV(){
|
||||
ByteBuffer buffer = ByteBuffer.wrap(this.iv);
|
||||
int number = buffer.getInt(12);
|
||||
number += 0x1F;
|
||||
buffer.position(12);
|
||||
buffer.putInt(number);
|
||||
this.iv = buffer.array();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished(){
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
@ -75,73 +107,66 @@ public abstract class FileEncryptedGetRequest extends FossilRequest {
|
||||
public void handleResponse(BluetoothGattCharacteristic characteristic) {
|
||||
byte[] value = characteristic.getValue();
|
||||
byte first = value[0];
|
||||
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")){
|
||||
if((first & 0x0F) == 1){
|
||||
if (characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) {
|
||||
if ((first & 0x0F) == 1) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(value);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
this.initDecryption();
|
||||
|
||||
short handle = buffer.getShort(1);
|
||||
int size = buffer.getInt(4);
|
||||
|
||||
byte status = buffer.get(3);
|
||||
|
||||
ResultCode code = ResultCode.fromCode(status);
|
||||
if(!code.inidicatesSuccess()){
|
||||
if (!code.inidicatesSuccess()) {
|
||||
throw new RuntimeException("FileGet error: " + code + " (" + status + ")");
|
||||
}
|
||||
|
||||
if(this.handle != handle){
|
||||
if (this.handle != handle) {
|
||||
throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
|
||||
}
|
||||
log("file size: " + size);
|
||||
fileBuffer = ByteBuffer.allocate(size);
|
||||
}else if((first & 0x0F) == 8){
|
||||
} else if ((first & 0x0F) == 8) {
|
||||
this.finished = true;
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.wrap(value);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
short handle = buffer.getShort(1);
|
||||
if(this.handle != handle){
|
||||
if (this.handle != handle) {
|
||||
throw new RuntimeException("handle: " + handle + " expected: " + this.handle);
|
||||
}
|
||||
|
||||
CRC32 crc = new CRC32();
|
||||
crc.update(this.fileData);
|
||||
|
||||
CRC32C c = new CRC32C();
|
||||
c.update(this.fileData, 0, fileData.length);
|
||||
|
||||
int crcExpected = buffer.getInt(8);
|
||||
|
||||
if((int) crc.getValue() != crcExpected){
|
||||
if ((int) crc.getValue() != crcExpected) {
|
||||
throw new RuntimeException("crc: " + crc.getValue() + " expected: " + crcExpected);
|
||||
}
|
||||
|
||||
this.handleFileData(this.fileData);
|
||||
}
|
||||
}else if(characteristic.getUuid().toString().equals("3dda0004-957f-7d4a-34a6-74696673696d")){
|
||||
SecretKeySpec keySpec = new SecretKeySpec(this.adapter.getSecretKey(), "AES");
|
||||
} else if (characteristic.getUuid().toString().equals("3dda0004-957f-7d4a-34a6-74696673696d")) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
|
||||
|
||||
byte[] fileIV = new byte[16];
|
||||
|
||||
|
||||
byte[] phoneRandomNumber = adapter.getPhoneRandomNumber();
|
||||
byte[] watchRandomNumber = adapter.getWatchRandomNumber();
|
||||
|
||||
System.arraycopy(phoneRandomNumber, 0, fileIV, 2, 6);
|
||||
System.arraycopy(watchRandomNumber, 0, fileIV, 9, 7);
|
||||
|
||||
fileIV[7]++;
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(fileIV));
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
|
||||
byte[] result = cipher.doFinal(value);
|
||||
|
||||
incrementIV();
|
||||
|
||||
fileBuffer.put(result, 1, result.length - 1);
|
||||
if((result[0] & 0x80) == 0x80){
|
||||
if ((result[0] & 0x80) == 0x80) {
|
||||
this.fileData = fileBuffer.array();
|
||||
}
|
||||
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
|
||||
} catch (BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@ -9,12 +8,9 @@ import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEQueue;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class FilePutRawRequest extends FossilRequest {
|
||||
public enum UploadState {INITIALIZED, UPLOADING, CLOSING, UPLOADED}
|
||||
@ -71,8 +67,10 @@ public class FilePutRawRequest extends FossilRequest {
|
||||
|
||||
this.prepareFilePackets(this.file);
|
||||
|
||||
for (byte[] packet : packets) {
|
||||
for (int i = 0, packetCount = packets.size(); i < packetCount; i++) {
|
||||
byte[] packet = packets.get(i);
|
||||
transactionBuilder.write(uploadCharacteristic, packet);
|
||||
onPacketWritten(transactionBuilder, i, packetCount);
|
||||
}
|
||||
|
||||
transactionBuilder.queue(adapter.getDeviceSupport().getQueue());
|
||||
@ -197,6 +195,11 @@ public class FilePutRawRequest extends FossilRequest {
|
||||
}
|
||||
|
||||
public void onFilePut(boolean success) {
|
||||
|
||||
}
|
||||
|
||||
public void onPacketWritten(TransactionBuilder transactionBuilder, int packetNr, int packetCount) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,32 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class FirmwareFilePutRequest extends FilePutRawRequest {
|
||||
public FirmwareFilePutRequest(byte[] firmwareBytes, FossilHRWatchAdapter adapter) {
|
||||
super((short) 0x00FF, firmwareBytes, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketWritten(TransactionBuilder transactionBuilder, int packetNr, int packetCount) {
|
||||
int progressPercent = (int) ((((float) packetNr) / packetCount) * 100);
|
||||
transactionBuilder.add(new SetProgressAction(GBApplication.getContext().getString(R.string.updatefirmwareoperation_update_in_progress), true, progressPercent, GBApplication.getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFilePut(boolean success) {
|
||||
Context context = GBApplication.getContext();
|
||||
if (success) {
|
||||
GB.updateInstallNotification(context.getString(R.string.updatefirmwareoperation_update_complete), false, 100, context);
|
||||
} else {
|
||||
GB.updateInstallNotification(context.getString(R.string.updatefirmwareoperation_write_failed), false, 0, context);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,13 @@ public class AssetImage extends AssetFile {
|
||||
this.indexZ = indexZ;
|
||||
}
|
||||
|
||||
protected AssetImage(byte[] fileData, String fileName, int angle, int distance, int indexZ) {
|
||||
super(fileName, fileData);
|
||||
this.angle = angle;
|
||||
this.distance = distance;
|
||||
this.indexZ = indexZ;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -16,7 +16,13 @@ public class AssetImageFactory {
|
||||
return new AssetImage(fileData, angle, distance, indexZ);
|
||||
}
|
||||
|
||||
// method created for creating empty files, which turned out not to work anyway
|
||||
private static AssetImage createAssetImage(byte[] fileData, String fileName, int angle, int distance, int indexZ){
|
||||
return new AssetImage(fileData, fileName, angle, distance, indexZ);
|
||||
}
|
||||
|
||||
public static AssetImage createAssetImage(Bitmap fileData, boolean RLEencode, int angle, int distance, int indexZ) throws IOException {
|
||||
if(RLEencode == (distance == 0)) throw new RuntimeException("when RLEencoding distance must be 0, image must be at center of screen");
|
||||
if(RLEencode){
|
||||
int height = fileData.getHeight();
|
||||
int width = fileData.getWidth();
|
||||
|
@ -17,26 +17,10 @@ public class CustomWidget extends Widget {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAngle() {
|
||||
return angle;
|
||||
}
|
||||
|
||||
public int getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setElements(ArrayList<CustomWidgetElement> elements) {
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
public void setAngle(int angle) {
|
||||
this.angle = angle;
|
||||
}
|
||||
|
||||
public void setDistance(int distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
@ -21,6 +21,22 @@ public class Widget implements Serializable {
|
||||
this.fontColor = fontColor;
|
||||
}
|
||||
|
||||
public int getAngle() {
|
||||
return angle;
|
||||
}
|
||||
|
||||
public int getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setAngle(int angle) {
|
||||
this.angle = angle;
|
||||
}
|
||||
|
||||
public void setDistance(int distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -4,9 +4,7 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FilePutRawRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.json.JsonPutRequest;
|
||||
|
||||
public class WidgetsPutRequest extends JsonPutRequest {
|
||||
|
@ -48,6 +48,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.hplus.EXRIZUK8Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.MakibesF68Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipLiteCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbips.AmazfitBipSCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgtr.AmazfitGTRCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitgts.AmazfitGTSCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.itag.ITagCoordinator;
|
||||
@ -217,6 +218,7 @@ public class DeviceHelper {
|
||||
result.add(new AmazfitCor2Coordinator());
|
||||
result.add(new AmazfitGTRCoordinator());
|
||||
result.add(new AmazfitGTSCoordinator());
|
||||
result.add(new AmazfitBipSCoordinator());
|
||||
result.add(new MiBand3Coordinator());
|
||||
result.add(new MiBand4Coordinator());
|
||||
result.add(new MiBand2HRXCoordinator());
|
||||
|
@ -51,10 +51,12 @@ import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventScreenshot;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.isRunningOreoOrLater;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_RECORDED_DATA_TYPES;
|
||||
|
||||
public class GB {
|
||||
|
||||
@ -112,6 +114,7 @@ public class GB {
|
||||
builder.addAction(R.drawable.ic_notification_disconnected, context.getString(R.string.controlcenter_disconnect), disconnectPendingIntent);
|
||||
if (GBApplication.isRunningLollipopOrLater() && DeviceHelper.getInstance().getCoordinator(device).supportsActivityDataFetching()) { //for some reason this fails on KK
|
||||
deviceCommunicationServiceIntent.setAction(DeviceService.ACTION_FETCH_RECORDED_DATA);
|
||||
deviceCommunicationServiceIntent.putExtra(EXTRA_RECORDED_DATA_TYPES, ActivityKind.TYPE_ACTIVITY);
|
||||
PendingIntent fetchPendingIntent = PendingIntent.getService(context, 1, deviceCommunicationServiceIntent, PendingIntent.FLAG_ONE_SHOT);
|
||||
builder.addAction(R.drawable.ic_action_fetch_activity_data, context.getString(R.string.controlcenter_fetch_activity_data), fetchPendingIntent);
|
||||
}
|
||||
|
@ -0,0 +1,342 @@
|
||||
/* Copyright (C) 2020 Ted Stein
|
||||
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.util;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.text.Normalizer;
|
||||
import java.text.Normalizer.Form;
|
||||
|
||||
// Implements Revised Romanization of Korean as well as we can without understanding any grammar.
|
||||
//
|
||||
// https://en.wikipedia.org/wiki/Revised_Romanization_of_Korean
|
||||
public class KoreanLanguageUtils {
|
||||
// https://en.wikipedia.org/wiki/Hangul_Jamo_%28Unicode_block%29
|
||||
private static final char JAMO_BLOCK_START = 0x1100;
|
||||
private static final char JAMO_BLOCK_END = 0x11FF;
|
||||
// https://en.wikipedia.org/wiki/Hangul_Syllables
|
||||
private static final char SYLLABLES_BLOCK_START = 0xAC00;
|
||||
private static final char SYLLABLES_BLOCK_END = 0xD7A3;
|
||||
// https://en.wikipedia.org/wiki/Hangul_Compatibility_Jamo
|
||||
private static final char COMPAT_JAMO_BLOCK_START = 0x3131;
|
||||
private static final char COMPAT_JAMO_BLOCK_END = 0x318E;
|
||||
|
||||
// Returns whether a char is in the given block. Both bounds are inclusive.
|
||||
private static boolean inRange(char c, char start, char end) {
|
||||
return c >= start && c <= end;
|
||||
}
|
||||
|
||||
// User input consisting of isolated jamo is usually mapped to the KS X 1001 compatibility
|
||||
// block, but jamo resulting from decomposed syllables are mapped to the modern one. This
|
||||
// function maps compat jamo to modern ones where possible and returns all other characters
|
||||
// unmodified.
|
||||
//
|
||||
// https://en.wikipedia.org/wiki/Hangul_Compatibility_Jamo
|
||||
// https://en.wikipedia.org/wiki/Hangul_Jamo_%28Unicode_block%29
|
||||
private static char decompatJamo(char jamo) {
|
||||
// KS X 1001 Hangul filler, not used in modern Unicode. A useful landmark in the
|
||||
// compatibility jamo block.
|
||||
// https://en.wikipedia.org/wiki/KS_X_1001#Hangul_Filler
|
||||
final char HANGUL_FILLER = 0x3164;
|
||||
|
||||
// Don't do anything to characters outside the compatibility jamo block.
|
||||
if (!inRange(jamo, COMPAT_JAMO_BLOCK_START, COMPAT_JAMO_BLOCK_END)) { return jamo; }
|
||||
|
||||
// Vowels are contiguous, in the same order, and unambiguous, so it's a simple offset.
|
||||
if (jamo >= 0x314F && jamo < HANGUL_FILLER) {
|
||||
return (char)(jamo - 0x1FEE);
|
||||
}
|
||||
|
||||
// Consonants are organized differently. No clean way to do this.
|
||||
//
|
||||
// The compatibility jamo block doesn't distinguish between Choseong (leading) and Jongseong
|
||||
// (final) positions, but the modern block does. We map to Choseong here.
|
||||
switch (jamo) {
|
||||
case 0x3131: return 0x1100; // ㄱ
|
||||
case 0x3132: return 0x1101; // ㄲ
|
||||
case 0x3134: return 0x1102; // ㄴ
|
||||
case 0x3137: return 0x1103; // ㄷ
|
||||
case 0x3138: return 0x1104; // ㄸ
|
||||
case 0x3139: return 0x1105; // ㄹ
|
||||
case 0x3141: return 0x1106; // ㅁ
|
||||
case 0x3142: return 0x1107; // ㅂ
|
||||
case 0x3143: return 0x1108; // ㅃ
|
||||
case 0x3145: return 0x1109; // ㅅ
|
||||
case 0x3146: return 0x110A; // ㅆ
|
||||
case 0x3147: return 0x110B; // ㅇ
|
||||
case 0x3148: return 0x110C; // ㅈ
|
||||
case 0x3149: return 0x110D; // ㅉ
|
||||
case 0x314A: return 0x110E; // ㅊ
|
||||
case 0x314B: return 0x110F; // ㅋ
|
||||
case 0x314C: return 0x1110; // ㅌ
|
||||
case 0x314D: return 0x1111; // ㅍ
|
||||
case 0x314E: return 0x1112; // ㅎ
|
||||
}
|
||||
|
||||
// The rest of the compatibility block consists of archaic compounds that are unlikely to be
|
||||
// encountered in modern systems. Just leave them alone.
|
||||
return jamo;
|
||||
}
|
||||
|
||||
// Transliterates jamo one at a time. Returns its input if it isn't in the modern jamo block.
|
||||
private static String transliterateSingleJamo(char jamo) {
|
||||
jamo = decompatJamo(jamo);
|
||||
|
||||
switch (jamo) {
|
||||
// Choseong (leading position consonants)
|
||||
case 0x1100: return "g"; // ㄱ
|
||||
case 0x1101: return "kk"; // ㄲ
|
||||
case 0x1102: return "n"; // ㄴ
|
||||
case 0x1103: return "d"; // ㄷ
|
||||
case 0x1104: return "tt"; // ㄸ
|
||||
case 0x1105: return "r"; // ㄹ
|
||||
case 0x1106: return "m"; // ㅁ
|
||||
case 0x1107: return "b"; // ㅂ
|
||||
case 0x1108: return "pp"; // ㅃ
|
||||
case 0x1109: return "s"; // ㅅ
|
||||
case 0x110A: return "ss"; // ㅆ
|
||||
case 0x110B: return ""; // ㅇ
|
||||
case 0x110C: return "j"; // ㅈ
|
||||
case 0x110D: return "jj"; // ㅉ
|
||||
case 0x110E: return "ch"; // ㅊ
|
||||
case 0x110F: return "k"; // ㅋ
|
||||
case 0x1110: return "t"; // ㅌ
|
||||
case 0x1111: return "p"; // ㅍ
|
||||
case 0x1112: return "h"; // ㅎ
|
||||
// Jungseong (vowels)
|
||||
case 0x1161: return "a"; // ㅏ
|
||||
case 0x1162: return "ae"; // ㅐ
|
||||
case 0x1163: return "ya"; // ㅑ
|
||||
case 0x1164: return "yae"; // ㅒ
|
||||
case 0x1165: return "eo"; // ㅓ
|
||||
case 0x1166: return "e"; // ㅔ
|
||||
case 0x1167: return "yeo"; // ㅕ
|
||||
case 0x1168: return "ye"; // ㅖ
|
||||
case 0x1169: return "o"; // ㅗ
|
||||
case 0x116A: return "wa"; // ㅘ
|
||||
case 0x116B: return "wae"; // ㅙ
|
||||
case 0x116C: return "oe"; // ㅚ
|
||||
case 0x116D: return "yo"; // ㅛ
|
||||
case 0x116E: return "u"; // ㅜ
|
||||
case 0x116F: return "wo"; // ㅝ
|
||||
case 0x1170: return "we"; // ㅞ
|
||||
case 0x1171: return "wi"; // ㅟ
|
||||
case 0x1172: return "yu"; // ㅠ
|
||||
case 0x1173: return "eu"; // ㅡ
|
||||
case 0x1174: return "ui"; // ㅢ
|
||||
case 0x1175: return "i"; // ㅣ
|
||||
// Jongseong (final position consonants)
|
||||
case 0x11A8: return "k"; // ㄱ
|
||||
case 0x11A9: return "k"; // ㄲ
|
||||
case 0x11AB: return "n"; // ㄴ
|
||||
case 0x11AE: return "t"; // ㄷ
|
||||
case 0x11AF: return "l"; // ㄹ
|
||||
case 0x11B7: return "m"; // ㅁ
|
||||
case 0x11B8: return "p"; // ㅂ
|
||||
case 0x11BA: return "t"; // ㅅ
|
||||
case 0x11BB: return "t"; // ㅆ
|
||||
case 0x11BC: return "ng"; // ㅇ
|
||||
case 0x11BD: return "t"; // ㅈ
|
||||
case 0x11BE: return "t"; // ㅊ
|
||||
case 0x11BF: return "k"; // ㅋ
|
||||
case 0x11C0: return "t"; // ㅌ
|
||||
case 0x11C1: return "p"; // ㅍ
|
||||
case 0x11C2: return "t"; // ㅎ
|
||||
}
|
||||
|
||||
// Input was not jamo.
|
||||
return String.valueOf(jamo);
|
||||
}
|
||||
|
||||
// Some combinations of ending jamo in one syllable and initial jamo in the next are romanized
|
||||
// irregularly. These exceptions are called "special provisions". In cases where multiple
|
||||
// romanizations are permitted, we use the one that's least commonly used elsewhere.
|
||||
//
|
||||
// Returns no value if either character is not in the modern jamo block, or if there is no
|
||||
// special provision for that pair of jamo.
|
||||
public static Optional<String> transliterateSpecialProvisions(char previousEnding, char nextInitial) {
|
||||
// Special provisions only apply if both characters are in the modern jamo block.
|
||||
if (!inRange(previousEnding, JAMO_BLOCK_START, JAMO_BLOCK_END)) { return Optional.empty(); }
|
||||
if (!inRange(nextInitial, JAMO_BLOCK_START, JAMO_BLOCK_END)) { return Optional.empty(); }
|
||||
|
||||
// Jongseong (final position) ㅎ has a number of special provisions.
|
||||
if (previousEnding == 0x11C2) { // ㅎ
|
||||
switch (nextInitial) {
|
||||
case 0x110B: return Optional.of("h"); // ㅇ
|
||||
case 0x1100: return Optional.of("k"); // ㄱ
|
||||
case 0x1102: return Optional.of("nn"); // ㄴ
|
||||
case 0x1103: return Optional.of("t"); // ㄷ
|
||||
case 0x1105: return Optional.of("nn"); // ㄹ
|
||||
case 0x1106: return Optional.of("nm"); // ㅁ
|
||||
case 0x1107: return Optional.of("p"); // ㅂ
|
||||
case 0x1109: return Optional.of("hs"); // ㅅ
|
||||
case 0x110C: return Optional.of("ch"); // ㅈ
|
||||
case 0x1112: return Optional.of("t"); // ㅎ
|
||||
default: return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, special provisions are denser when grouped by the second jamo.
|
||||
switch (nextInitial) {
|
||||
case 0x1100: // ㄱ
|
||||
switch (previousEnding) {
|
||||
case 0x11AB: return Optional.of("n-g"); // ㄴ
|
||||
default: return Optional.empty();
|
||||
}
|
||||
case 0x1102: // ㄴ
|
||||
switch (previousEnding) {
|
||||
case 0x11A8: return Optional.of("ngn"); // ㄱ
|
||||
case 0x11AE: // ㄷ
|
||||
case 0x11BA: // ㅅ
|
||||
case 0x11BD: // ㅈ
|
||||
case 0x11BE: // ㅊ
|
||||
case 0x11C0: // ㅌ
|
||||
return Optional.of("nn");
|
||||
case 0x11AF: return Optional.of("ll"); // ㄹ
|
||||
case 0x11B8: return Optional.of("mn"); // ㅂ
|
||||
default: return Optional.empty();
|
||||
}
|
||||
case 0x1105: // ㄹ
|
||||
switch (previousEnding) {
|
||||
case 0x11A8: // ㄱ
|
||||
case 0x11AB: // ㄴ
|
||||
case 0x11AF: // ㄹ
|
||||
return Optional.of("ll");
|
||||
case 0x11AE: // ㄷ
|
||||
case 0x11BA: // ㅅ
|
||||
case 0x11BD: // ㅈ
|
||||
case 0x11BE: // ㅊ
|
||||
case 0x11C0: // ㅌ
|
||||
return Optional.of("nn");
|
||||
case 0x11B7: // ㅁ
|
||||
case 0x11B8: // ㅂ
|
||||
return Optional.of("mn");
|
||||
case 0x11BC: return Optional.of("ngn"); // ㅇ
|
||||
default: return Optional.empty();
|
||||
}
|
||||
case 0x1106: // ㅁ
|
||||
switch (previousEnding) {
|
||||
case 0x11A8: return Optional.of("ngm"); // ㄱ
|
||||
case 0x11AE: // ㄷ
|
||||
case 0x11BA: // ㅅ
|
||||
case 0x11BD: // ㅈ
|
||||
case 0x11BE: // ㅊ
|
||||
case 0x11C0: // ㅌ
|
||||
return Optional.of("nm");
|
||||
case 0x11B8: return Optional.of("mm"); // ㅂ
|
||||
default: return Optional.empty();
|
||||
}
|
||||
case 0x110B: // ㅇ
|
||||
switch (previousEnding) {
|
||||
case 0x11A8: return Optional.of("g"); // ㄱ
|
||||
case 0x11AE: return Optional.of("d"); // ㄷ
|
||||
case 0x11AF: return Optional.of("r"); // ㄹ
|
||||
case 0x11B8: return Optional.of("b"); // ㅂ
|
||||
case 0x11BA: return Optional.of("s"); // ㅅ
|
||||
case 0x11BC: return Optional.of("ng-"); // ㅇ
|
||||
case 0x11BD: return Optional.of("j"); // ㅈ
|
||||
case 0x11BE: return Optional.of("ch"); // ㅊ
|
||||
default: return Optional.empty();
|
||||
}
|
||||
case 0x110F: // ㅋ
|
||||
switch (previousEnding) {
|
||||
case 0x11A8: return Optional.of("k-k"); // ㄱ
|
||||
default: return Optional.empty();
|
||||
}
|
||||
case 0x1110: // ㅌ
|
||||
switch (previousEnding) {
|
||||
case 0x11AE: // ㄷ
|
||||
case 0x11BA: // ㅅ
|
||||
case 0x11BD: // ㅈ
|
||||
case 0x11BE: // ㅊ
|
||||
case 0x11C0: // ㅌ
|
||||
return Optional.of("t-t");
|
||||
default: return Optional.empty();
|
||||
}
|
||||
case 0x1111: // ㅍ
|
||||
switch (previousEnding) {
|
||||
case 0x11B8: return Optional.of("p-p"); // ㅂ
|
||||
default: return Optional.empty();
|
||||
}
|
||||
default: return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
// Decompose a syllable into several jamo. Returns its input if that isn't possible.
|
||||
public static char[] decompose(char syllable) {
|
||||
String normalized = Normalizer.normalize(String.valueOf(syllable), Normalizer.Form.NFD);
|
||||
return normalized.toCharArray();
|
||||
}
|
||||
|
||||
// Transliterate any Hangul in the given string. Leaves any non-Hangul characters unmodified.
|
||||
public static String transliterate(String txt) {
|
||||
if (txt == null || txt.isEmpty()) {
|
||||
return txt;
|
||||
}
|
||||
|
||||
// Most of the bulk of these loops is for handling special provisions - situations where the
|
||||
// last jamo of one syllable and the first of the next need to be romanized as a pair in an
|
||||
// irregular way.
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean nextInitialJamoConsumed = false;
|
||||
char[] syllables = txt.toCharArray();
|
||||
for (int i = 0; i < syllables.length; i++) {
|
||||
char thisSyllable = syllables[i];
|
||||
// If this isn't in any of the Hangul blocks we know about, emit it as-is.
|
||||
if (!inRange(thisSyllable, JAMO_BLOCK_START, JAMO_BLOCK_END)
|
||||
&& !inRange(thisSyllable, SYLLABLES_BLOCK_START, SYLLABLES_BLOCK_END)
|
||||
&& !inRange(thisSyllable, COMPAT_JAMO_BLOCK_START, COMPAT_JAMO_BLOCK_END)) {
|
||||
builder.append(thisSyllable);
|
||||
continue;
|
||||
}
|
||||
|
||||
char[] theseJamo = decompose(thisSyllable);
|
||||
for (int j = 0; j < theseJamo.length; j++) {
|
||||
char thisJamo = theseJamo[j];
|
||||
|
||||
// If we already transliterated the first jamo of this syllable as part of a special
|
||||
// provision, skip it. Otherwise, handle it in the unconditional else branch.
|
||||
if (j == 0 && nextInitialJamoConsumed) {
|
||||
nextInitialJamoConsumed = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is the last jamo of this syllable and not the last syllable of the
|
||||
// string, check for special provisions. If the next char is whitespace or not
|
||||
// Hangul, it's the responsibility of transliterateSpecialProvisions() to return no
|
||||
// value.
|
||||
if (j == theseJamo.length - 1 && i < syllables.length - 1) {
|
||||
char nextSyllable = syllables[i + 1];
|
||||
char nextJamo = decompose(nextSyllable)[0];
|
||||
Optional<String> specialProvision = transliterateSpecialProvisions(thisJamo, nextJamo);
|
||||
if (specialProvision.isPresent()) {
|
||||
builder.append(specialProvision.get());
|
||||
nextInitialJamoConsumed = true;
|
||||
} else {
|
||||
// No special provision applies. Transliterate in isolation.
|
||||
builder.append(transliterateSingleJamo(thisJamo));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Everything else is transliterated in isolation.
|
||||
builder.append(transliterateSingleJamo(thisJamo));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
@ -77,12 +77,14 @@ public class LanguageUtils {
|
||||
put('ق', "q"); put('ك', "k"); put('ل', "l"); put('م', "m"); put('ن', "n"); put('ه', "h");
|
||||
put('و', "w"); put('ي', "y"); put('ى', "a"); put('ﺓ', "");
|
||||
put('آ', "2"); put('ئ', "2"); put('إ', "2"); put('ؤ', "2"); put('أ', "2"); put('ء', "2");
|
||||
put('٠', "0"); put('١', "1"); put('٢', "2"); put('٣', "3"); put('٤', "4"); put('٥', "5");
|
||||
put('٦', "6"); put('٧', "7"); put('٨', "8"); put('٩', "9");
|
||||
|
||||
// Persian(Farsi)
|
||||
put('پ', "p"); put('چ', "ch"); put('ژ', "zh"); put('ک', "k"); put('گ', "g"); put('ی', "y"); put('', " ");
|
||||
put('؟', "?"); put('٪', "%"); put('؛', ";"); put('،', ","); put('۱', "1"); put('۲', "2"); put('۳', "3");
|
||||
put('۴', "4"); put('۵', "5"); put('۶', "6"); put('۷', "7"); put('۸', "8"); put('۹', "9"); put('۰', "0");
|
||||
put('»', "<"); put('«', ">"); put('ِ', "e"); put('َ', "a"); put('ُ', "o"); put('ّ', "");
|
||||
put('»', "<"); put('«', ">"); put('ِ', "e"); put('َ', "a"); put('ُ', "o"); put('ّ', "");
|
||||
|
||||
// Polish
|
||||
put('Ł', "L"); put('ł', "l");
|
||||
@ -114,18 +116,21 @@ public class LanguageUtils {
|
||||
return txt;
|
||||
}
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
StringBuilder messageBuilder = new StringBuilder();
|
||||
|
||||
// Simple, char-by-char transliteration.
|
||||
char[] chars = txt.toCharArray();
|
||||
|
||||
for (char c : chars)
|
||||
{
|
||||
message.append(transliterate(c));
|
||||
messageBuilder.append(transliterate(c));
|
||||
}
|
||||
String message = messageBuilder.toString();
|
||||
|
||||
String messageString = BengaliLanguageUtils.transliterate(message.toString());
|
||||
// More complex transliteration for specific languages.
|
||||
message = BengaliLanguageUtils.transliterate(message);
|
||||
message = KoreanLanguageUtils.transliterate(message);
|
||||
|
||||
return flattenToAscii(messageString);
|
||||
return flattenToAscii(message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,4 +96,26 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="add widget" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:weightSum="2"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/qhybrid_unset_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="delete background"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/qhybrid_set_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="set background"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
35
app/src/main/res/layout/activity_qhybrid_image_edit.xml
Normal file
35
app/src/main/res/layout/activity_qhybrid_image_edit.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:weightSum="1">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:id="@+id/qhybrid_image_edit_container"
|
||||
android:layout_above="@id/qhybrid_image_edit_okay"
|
||||
android:layout_alignParentTop="true">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/qhybrid_image_edit_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/holo_red_dark"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/qhybrid_image_edit_image_overlay"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ok"
|
||||
android:id="@+id/qhybrid_image_edit_okay"
|
||||
android:layout_alignParentBottom="true"/>
|
||||
|
||||
</RelativeLayout>
|
@ -845,4 +845,9 @@
|
||||
<string name="pref_title_upper_button_function">Botó superior</string>
|
||||
<string name="pref_title_middle_button_function">Botó mitger</string>
|
||||
<string name="pref_title_lower_button_function">Botó inferior</string>
|
||||
<string name="pref_title_relax_firmware_checks">Activeu-ho si voleu instal·lar microprogramari no destinat al vostre aparell (sota la vostra responsabilitat)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Relaxa les comprovacions de microprogramari</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="pref_title_vibration_strength">Intensitat de vibració</string>
|
||||
<string name="pref_header_auto_fetch">Recollida automàtica</string>
|
||||
</resources>
|
@ -816,7 +816,7 @@
|
||||
<string name="prefs_button_triple_press_action_selection_title">Akce události 3</string>
|
||||
<string name="prefs_button_variable_actions">Detailní nastavení stisku tlačítka</string>
|
||||
<string name="prefs_button_long_press_action_selection_title">Akce pro dlouhý stisk</string>
|
||||
<string name="alarm_snooze">Později...</string>
|
||||
<string name="alarm_snooze">Odložit</string>
|
||||
<string name="error_no_location_access">Přístup k poloze musí být díky systému Android přístupů povolen a zapnut, aby bylo možno správně naskenovat zařízení</string>
|
||||
<string name="devicetype_itag">iTag</string>
|
||||
<string name="pref_title_allow_high_mtu">Povolit vyšší MTU</string>
|
||||
@ -834,4 +834,21 @@
|
||||
<string name="find_lost_device_you_found_it">Nalezeno!</string>
|
||||
<string name="pref_title_force_white_color_scheme">Vynutit barevné schéma Černá na bílé</string>
|
||||
<string name="pref_summary_force_white_color_scheme">Užitečné, pokud máte hodinky s tmavými ručičkami</string>
|
||||
<string name="find_my_phone_notification">Najít telefon</string>
|
||||
<string name="notification_channel_high_priority_name">Gadgetbridge oznámení s vysokou prioritou</string>
|
||||
<string name="pref_title_custom_deviceicon">Zobrazit v oznámení ikonu připojeného zařízení</string>
|
||||
<string name="pref_summary_custom_deviceicon">Zobrazit ikonu konkrétního připojeného zařízení v oznámení Androidu namísto ikony Gadgetbridge</string>
|
||||
<string name="hr_appname_wellness">Wellness</string>
|
||||
<string name="hr_appname_workout">Cvičení</string>
|
||||
<string name="hr_appname_stopwatch">Stopky</string>
|
||||
<string name="hr_appname_commute">Dojíždění</string>
|
||||
<string name="pref_title_upper_button_function">Horní Tlačítko</string>
|
||||
<string name="pref_title_middle_button_function">Prostřední Tlačítko</string>
|
||||
<string name="pref_title_lower_button_function">Dolní Tlačítko</string>
|
||||
<string name="pref_title_vibration_strength">Síla vibrací</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="pref_title_relax_firmware_checks">Aktivujte tuto možnost, pokud chcete flashovat firmware, který není určen pro vaše zařízení (na vlastní nebezpečí)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Uvolněte kontroly firmwaru</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Nakreslete kruhy widgetu</string>
|
||||
<string name="pref_header_auto_fetch">Stahovat automaticky</string>
|
||||
</resources>
|
@ -54,7 +54,7 @@
|
||||
<!--Strings related to Settings-->
|
||||
<string name="title_activity_settings">Einstellungen</string>
|
||||
<string name="pref_header_general">Allgemeine Einstellungen</string>
|
||||
<string name="pref_title_general_autoconnectonbluetooth">Mit Gadgetbridge-Gerät verbinden, wenn Bluetooth eingeschaltet ist</string>
|
||||
<string name="pref_title_general_autoconnectonbluetooth">Mit Gadgetbridge-Gerät verbinden, wenn Bluetooth eingeschaltet wird</string>
|
||||
<string name="pref_title_general_autostartonboot">Automatisch starten</string>
|
||||
<string name="pref_title_general_autoreconnect">Verbindung automatisch wiederherstellen</string>
|
||||
<string name="pref_title_audio_player">Bevorzugter Audioplayer</string>
|
||||
@ -78,7 +78,7 @@
|
||||
<string name="pref_title_notifications_generic">Unterstützung allgemeine Benachrichtigung</string>
|
||||
<string name="pref_title_whenscreenon">…auch wenn der Bildschirm an ist</string>
|
||||
<string name="pref_title_notification_filter">Bitte nicht stören</string>
|
||||
<string name="pref_summary_notification_filter">Unerwünschte Benachrichtigungen werden in diesem Modus gestoppt</string>
|
||||
<string name="pref_summary_notification_filter">Unerwünschte Benachrichtigungen werden in diesem Modus unterdrückt</string>
|
||||
<string name="pref_title_transliteration">Umwandlung</string>
|
||||
<string name="pref_summary_transliteration">Aktiviere dies, falls dein Gerät keine Unterstützung für die Schriftart deiner Sprache hat</string>
|
||||
<string name="always">Immer</string>
|
||||
@ -131,7 +131,7 @@
|
||||
<string name="pref_title_pebble_forceprotocol">Benachrichtigungsprotokoll erzwingen</string>
|
||||
<string name="pref_summary_pebble_forceprotocol">Diese Option erzwingt das neuste Benachrichtigungsprotokoll abhängig von der Firmwareversion. NUR EINSCHALTEN, WENN DU WEISST, WAS DU TUST!</string>
|
||||
<string name="pref_title_pebble_forceuntested">Ungetestete Features aktivieren</string>
|
||||
<string name="pref_summary_pebble_forceuntested">Ungetestete Funktionen aktivieren. WEISST DU WAS DU TUST!</string>
|
||||
<string name="pref_summary_pebble_forceuntested">Aktiviere ungetestete Funktionen. SEI DIR SICHER WAS DU DA TUST!</string>
|
||||
<string name="pref_title_pebble_forcele">BLE immer bevorzugen</string>
|
||||
<string name="pref_summary_pebble_forcele">Nutze die experimentelle LE-Unterstützung für alle Pebbles anstelle von BT-Classic. Dies erfordert zuerst eine Kopplung mit Nicht-LE und dann Pebble LE</string>
|
||||
<string name="pref_title_pebble_mtu_limit">Pebble 2/LE GATT MTU Limit</string>
|
||||
@ -145,7 +145,7 @@
|
||||
<string name="pref_title_timeformat">Zeitformat</string>
|
||||
<string name="pref_title_screentime">Bildschirm-An-Dauer</string>
|
||||
<string name="prefs_title_all_day_heart_rate">Ganztägige Herzfrequenzmessung</string>
|
||||
<string name="preferences_hplus_settings">HPlus/Makibes Einstellungen</string>
|
||||
<string name="preferences_hplus_settings">HPlus/Makibes-Einstellungen</string>
|
||||
<string name="not_connected">Nicht verbunden</string>
|
||||
<string name="connecting">Verbindung wird hergestellt</string>
|
||||
<string name="connected">Verbunden</string>
|
||||
@ -192,7 +192,7 @@
|
||||
<string name="pairing_already_bonded">Bereits an %1$s (%2$s) gebunden, verbinden…</string>
|
||||
<string name="message_cannot_pair_no_mac">Keine MAC-Adresse erhalten, koppeln nicht möglich.</string>
|
||||
<string name="preferences_category_device_specific_settings">Gerätespezifische Einstellungen</string>
|
||||
<string name="preferences_miband_settings">Mi Band / Amazfit Einstellungen</string>
|
||||
<string name="preferences_miband_settings">Mi Band- / Amazfit-Einstellungen</string>
|
||||
<string name="male">Männlich</string>
|
||||
<string name="female">Weiblich</string>
|
||||
<string name="other">Andere</string>
|
||||
@ -268,7 +268,7 @@
|
||||
<string name="weeksleepchart_today_sleep_description">Schlaf heute, Ziel: %1$s</string>
|
||||
<string name="weekstepschart_steps_a_week">Schritte pro Woche</string>
|
||||
<string name="activity_sleepchart_activity_and_sleep">Aktivität</string>
|
||||
<string name="updating_firmware">Firmware aktualisieren…</string>
|
||||
<string name="updating_firmware">Aktualisiere Firmware…</string>
|
||||
<string name="fwapp_install_device_not_ready">Datei kann nicht installiert werden, Gerät nicht bereit.</string>
|
||||
<string name="installhandler_firmware_name">%1$s: %2$s %3$s</string>
|
||||
<string name="miband_fwinstaller_compatible_version">Kompatible Version</string>
|
||||
@ -352,7 +352,7 @@
|
||||
<string name="charts_legend_heartrate">Herzfrequenz</string>
|
||||
<string name="live_activity_heart_rate">Herzfrequenz</string>
|
||||
<string name="pref_title_pebble_health_store_raw">Rohdaten in der Datenbank speichern</string>
|
||||
<string name="pref_summary_pebble_health_store_raw">Speichert Daten \"wie sie sind\" und erhöht die Datenbanknutzung, um eine spätere Auswertung zu ermöglichen.</string>
|
||||
<string name="pref_summary_pebble_health_store_raw">Speichert Daten „wie sie sind“ und erhöht die Datenbanknutzung, um eine spätere Auswertung zu ermöglichen.</string>
|
||||
<string name="action_db_management">Datenbankverwaltung</string>
|
||||
<string name="title_activity_db_management">Datenbankverwaltung</string>
|
||||
<string name="activity_db_management_import_export_explanation">Die Datenbankoperationen verwenden den folgenden Pfad auf deinem Gerät.
|
||||
@ -487,7 +487,7 @@
|
||||
<string name="pref_title_auto_export_interval">Exportintervall</string>
|
||||
<string name="pref_summary_auto_export_interval">Alle %d Stunden exportieren</string>
|
||||
<string name="notif_export_failed_title">Datenbankexport fehlgeschlagen! Bitte überprüfe deine Einstellungen.</string>
|
||||
<string name="mi2_prefs_button_press_broadcast_summary">Broadcast-Nachricht, die mit dem Ereignis gesendet wurde. Der Parameter \"button_id\" wird automatisch zu jeder Nachricht hinzugefügt.</string>
|
||||
<string name="mi2_prefs_button_press_broadcast_summary">Broadcast-Nachricht, die mit dem Ereignis gesendet wurde. Der Parameter „button_id“ wird automatisch zu jeder Nachricht hinzugefügt.</string>
|
||||
<string name="mi2_prefs_button_press_count_match_delay_summary">Verzögerung nach einer Tastenaktion (Zahl in button_id) oder 0 für sofort</string>
|
||||
<string name="spanish">Spanisch</string>
|
||||
<string name="on">Ein</string>
|
||||
@ -541,7 +541,7 @@
|
||||
<string name="whitelist_all_for_notifications">Whitelist für alle Benachrichtigungen</string>
|
||||
<string name="pref_auto_fetch_summary">Abruf erfolgt beim Entsperren des Bildschirms. Funktioniert nur, wenn ein Sperrmechanismus eingestellt ist!</string>
|
||||
<string name="watch9_pairing_tap_hint">Wenn deine Uhr vibriert, schüttel das Gerät oder drücke die Taste.</string>
|
||||
<string name="preferences_qhybrid_settings">Q Hybrid Einstellungen</string>
|
||||
<string name="preferences_qhybrid_settings">Q Hybrid-Einstellungen</string>
|
||||
<string name="watch9_calibration_button">Kalibrieren</string>
|
||||
<string name="title_activity_watch9_pairing">Watch 9 koppeln</string>
|
||||
<string name="watch9_time_minutes">Minuten:</string>
|
||||
@ -606,7 +606,7 @@
|
||||
<string name="pref_invalid_frequency_message">Bitte eine Frequenz zwischen 87,5 und 108,0 eingeben</string>
|
||||
<string name="language_and_region_prefs">Sprach- und Regionseinstellungen</string>
|
||||
<string name="debugactivity_really_factoryreset_title">Wirklich auf Werkseinstellungen zurücksetzen\?</string>
|
||||
<string name="debugactivity_really_factoryreset">Beim Zurücksetzen auf die Werkseinstellungen werden alle Daten vom angeschlossenen Gerät gelöscht (falls unterstützt). Xiaomi/Huami-Geräte ändern auch die Bluetooth-MAC-Adresse, so dass sie als neue Geräte bei Gadgetbridge erscheinen.</string>
|
||||
<string name="debugactivity_really_factoryreset">Beim Zurücksetzen auf die Werkseinstellungen werden alle Daten vom angeschlossenen Gerät gelöscht (falls unterstützt). Xiaomi/Huami-Geräte wechseln dabei auch die Bluetooth-MAC-Adresse, so dass sie als neue Geräte bei Gadgetbridge erscheinen.</string>
|
||||
<string name="pref_rtl_max_line_length_summary">Verlängert oder verkürzt die Zeilen, in die der Rechts-nach-Links Text getrennt wird</string>
|
||||
<string name="notif_battery_low_extended">%1$s Akku schwach: %2$s</string>
|
||||
<string name="lack_of_sleep">Schlafmangel: %1$s</string>
|
||||
@ -641,7 +641,7 @@
|
||||
<string name="activity_prefs_distance_meters">Tägliches Ziel: zurückgelegte Strecke in Meter</string>
|
||||
<string name="activity_prefs_activetime_minutes">Tägliches Ziel: aktive Zeit in Minuten</string>
|
||||
<!-- ZeTime Preferences -->
|
||||
<string name="zetime_title_settings">ZeTime Einstellungen</string>
|
||||
<string name="zetime_title_settings">ZeTime-Einstellungen</string>
|
||||
<string name="zetime_title_screentime">Display-Aktivierungsdauer in Sekunden</string>
|
||||
<string name="activity_prefs_alarm_max_heart_rate">Hohe Herzfrequenzschwelle</string>
|
||||
<string name="activity_prefs_alarm_min_heart_rate">Niedrige Herzfrequenzschwelle</string>
|
||||
@ -764,7 +764,7 @@
|
||||
<item quantity="one">%d Std</item>
|
||||
<item quantity="other">%d Std</item>
|
||||
</plurals>
|
||||
<string name="preferences_makibes_hr3_settings">Makibes HR3 Einstellungen</string>
|
||||
<string name="preferences_makibes_hr3_settings">Makibes HR3-Einstellungen</string>
|
||||
<string name="devicetype_makibes_hr3">Makibes HR3</string>
|
||||
<string name="devicetype_amazfit_bip_lite">Amazfit Bip Lite</string>
|
||||
<string name="prefs_find_phone">Telefon finden</string>
|
||||
@ -792,7 +792,7 @@
|
||||
<string name="pref_chart_heartrate_color_orange">Orange</string>
|
||||
<string name="pref_title_chart_heartrate_color">Farbe der Herzfrequenz</string>
|
||||
<string name="pref_title_chart_sleep_rolling_24_hour">Schlafbereich</string>
|
||||
<string name="pref_chart_sleep_rolling_24_on">Letzten 24 Stunden</string>
|
||||
<string name="pref_chart_sleep_rolling_24_on">Letzte 24 Stunden</string>
|
||||
<string name="pref_chart_sleep_rolling_24_off">Mittag bis Mittag</string>
|
||||
<string name="devicetype_amazfit_gts">Amazfit GTS</string>
|
||||
<string name="fw_upgrade_notice_amazfitgts">Du bist dabei, die Firmware %s auf deine Amazfit GTS zu installieren.
|
||||
@ -831,7 +831,7 @@
|
||||
<string name="prefs_button_single_press_action_selection_title">Aktion bei einem einzigen Tastendruck</string>
|
||||
<string name="prefs_button_double_press_action_selection_title">Aktion bei 2 Tastendrücken</string>
|
||||
<string name="prefs_button_triple_press_action_selection_title">Aktion bei 3 Tastendrücken</string>
|
||||
<string name="pref_title_allow_high_mtu">Hohe MTU erlauben</string>
|
||||
<string name="pref_title_allow_high_mtu">Größere MTU erlauben</string>
|
||||
<string name="pref_summary_sync_calendar">Aktiviert Kalendererinnerungen, auch wenn die Verbindung getrennt ist</string>
|
||||
<string name="pref_title_sync_caldendar">Kalenderereignisse synchronisieren</string>
|
||||
<string name="hr_widget_heart_rate">Herzfrequenz</string>
|
||||
@ -855,4 +855,11 @@
|
||||
<string name="pref_title_upper_button_function">Obere Taste</string>
|
||||
<string name="pref_title_middle_button_function">Mittlere Taste</string>
|
||||
<string name="pref_title_lower_button_function">Untere Taste</string>
|
||||
<string name="pref_title_vibration_strength">Vibrationsstärke</string>
|
||||
<string name="hr_appname_commute">Pendeln</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Firmwareüberprüfung deaktivieren</string>
|
||||
<string name="pref_title_relax_firmware_checks">Aktiviere das flashen von Firmware, die nicht für dieses Gerät bestimmt ist (auf eigenes Risiko)</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Widget-Kreise zeichnen</string>
|
||||
<string name="pref_header_auto_fetch">Automatischer Abruf</string>
|
||||
</resources>
|
853
app/src/main/res/values-en-rGB/strings.xml
Normal file
853
app/src/main/res/values-en-rGB/strings.xml
Normal file
@ -0,0 +1,853 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="pref_title_chart_heartrate_color">Heart rate colour</string>
|
||||
<string name="pref_title_force_white_color_scheme">Force black on white colour scheme</string>
|
||||
<string name="controlcenter_change_led_color">Change LED colour</string>
|
||||
<string name="notif_battery_low_percent">%1$s battery left: %2$s%%</string>
|
||||
<plurals name="widget_alarm_target_hours">
|
||||
<item quantity="one">%d hour</item>
|
||||
<item quantity="other">%d hours</item>
|
||||
</plurals>
|
||||
<string name="pbwinstallhandler_app_item">%1$s (%2$s)</string>
|
||||
<string name="installhandler_firmware_name">%1$s: %2$s %3$s</string>
|
||||
<string name="notif_battery_low_extended">%1$s battery low: %2$s</string>
|
||||
<string name="notif_battery_low">%1$s battery low</string>
|
||||
<string name="device_with_rssi">%1$s (%2$s)</string>
|
||||
<string name="appversion_by_creator">%1$s by %2$s</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Draw widget circles</string>
|
||||
<string name="pref_header_auto_fetch">Auto fetch</string>
|
||||
<string name="pref_title_relax_firmware_checks">Enable this if you want to flash a firmware not intended for you device (at your own risk)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Relax firmware checks</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="pref_title_vibration_strength">Vibration strength</string>
|
||||
<string name="pref_title_lower_button_function">Lower Button</string>
|
||||
<string name="pref_title_middle_button_function">Middle Button</string>
|
||||
<string name="pref_title_upper_button_function">Upper Button</string>
|
||||
<string name="hr_appname_commute">Commute</string>
|
||||
<string name="hr_appname_stopwatch">Stopwatch</string>
|
||||
<string name="hr_appname_workout">Workout</string>
|
||||
<string name="hr_appname_wellness">Wellness</string>
|
||||
<string name="pref_summary_custom_deviceicon">Show a device specific Android notification icon instead the Gadgetbridge icon when connected</string>
|
||||
<string name="pref_title_custom_deviceicon">Show device specific notification icon</string>
|
||||
<string name="notification_channel_high_priority_name">Gadgetbridge notifications high priority</string>
|
||||
<string name="find_my_phone_notification">Find my phone</string>
|
||||
<string name="pref_summary_force_white_color_scheme">Useful if you your watch has dark hands</string>
|
||||
<string name="find_lost_device_you_found_it">Found it!</string>
|
||||
<string name="hr_widget_nothing">Nothing</string>
|
||||
<string name="hr_widget_weather">Weather</string>
|
||||
<string name="hr_widget_battery">Battery</string>
|
||||
<string name="hr_widget_calories">Calories</string>
|
||||
<string name="hr_widget_active_minutes">Active minutes</string>
|
||||
<string name="hr_widget_date">Date</string>
|
||||
<string name="hr_widget_steps">Steps</string>
|
||||
<string name="hr_widget_heart_rate">Heart rate</string>
|
||||
<string name="pref_title_sync_caldendar">Sync calendar events</string>
|
||||
<string name="pref_summary_sync_calendar">Enables calendar alerts, even when disconnected</string>
|
||||
<string name="pref_summary_allow_high_mtu">Increases transfer speed, but might not work on some Android devices.</string>
|
||||
<string name="pref_title_allow_high_mtu">Allow high MTU</string>
|
||||
<string name="devicetype_itag">iTag</string>
|
||||
<string name="error_no_location_access">Location access must be granted and enabled for scanning to work properly</string>
|
||||
<string name="alarm_snooze">Snooze</string>
|
||||
<string name="prefs_button_long_press_action_selection_title">Long press button action</string>
|
||||
<string name="prefs_button_variable_actions">Detailed button press settings</string>
|
||||
<string name="prefs_button_triple_press_action_selection_title">Event 3 action</string>
|
||||
<string name="prefs_button_double_press_action_selection_title">Event 2 action</string>
|
||||
<string name="prefs_button_single_press_action_selection_title">Event 1 action</string>
|
||||
<string name="devicetype_y5">Y5</string>
|
||||
<string name="devicetype_banglejs">Bangle.js</string>
|
||||
<string name="pref_summary_disable_new_ble_scanning">Check this option if your device cannot be found during discovery</string>
|
||||
<string name="pref_disable_new_ble_scanning">Disable new BLE scanning</string>
|
||||
<string name="qhybrid_offset_time_by">offset time by</string>
|
||||
<string name="qhybrid_changes_delay_prompt">change might take some seconds…</string>
|
||||
<string name="qhybrid_offset_timezone">offset timezone by</string>
|
||||
<string name="qhybrid_buttons_overwrite_error">Error overwriting buttons</string>
|
||||
<string name="qhybrid_buttons_overwrite_success">Buttons overwritten</string>
|
||||
<string name="qhybrid_prompt_million_steps">Please set the step count to a million to activate that.</string>
|
||||
<string name="qhybrid_use_activity_hand_as_notification_counter">use activity hand as notification counter</string>
|
||||
<string name="qhybrid_overwrite_buttons">overwrite buttons</string>
|
||||
<string name="qhybrid_second_timezone_offset_relative_to_utc">second timezone offset relative to UTC</string>
|
||||
<string name="qhybrid_time_shift">time shift</string>
|
||||
<string name="qhybrid_goal_in_steps">Goal in steps</string>
|
||||
<string name="qhybrid_vibration_strength">vibration strength:</string>
|
||||
<string name="watch_not_connected">Watch not connected</string>
|
||||
<string name="preferences_qhybrid_settings">Q Hybrid Settings</string>
|
||||
<string name="devicetype_qhybrid">Fossil Q Hybrid</string>
|
||||
<string name="fw_upgrade_notice_amazfitgts">You are about to install the %s firmware on your Amazfit GTS.
|
||||
\n
|
||||
\nPlease make sure to install the .fw file, then the .res file, and finally the .gps file. Your watch will reboot after installing the .fw file.
|
||||
\n
|
||||
\nNote: You do not have to install .res and .gps if these files are exactly the same as the ones previously installed.
|
||||
\n
|
||||
\nPROCEED AT YOUR OWN RISK!</string>
|
||||
<string name="devicetype_amazfit_gts">Amazfit GTS</string>
|
||||
<string name="pref_chart_sleep_rolling_24_off">Noon to noon</string>
|
||||
<string name="pref_chart_sleep_rolling_24_on">Past 24 hours</string>
|
||||
<string name="pref_title_chart_sleep_rolling_24_hour">Sleep range</string>
|
||||
<string name="pref_chart_heartrate_color_orange">Orange</string>
|
||||
<string name="pref_chart_heartrate_color_red">Red</string>
|
||||
<string name="fw_upgrade_notice_amazfitgtr">You are about to install the %s firmware on your Amazfit GTR.
|
||||
\n
|
||||
\nPlease make sure to install the .fw file, then the .res file, and finally the .gps file. Your watch will reboot after installing the .fw file.
|
||||
\n
|
||||
\nNote: You do not have to install .res and .gps if these files are exactly the same as the ones previously installed.
|
||||
\n
|
||||
\nPROCEED AT YOUR OWN RISK!</string>
|
||||
<string name="devicetype_amazfit_gtr">Amazfit GTR</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip_lite">You are about to install the %s firmware on your Amazfit Bip Lite.
|
||||
\n
|
||||
\nPlease make sure to install the .fw file, and after that the .res file. Your watch will reboot after installing the .fw file.
|
||||
\n
|
||||
\nNote: You do not have to install .res if it is exactly the same as the one previously installed.
|
||||
\n
|
||||
\nPROCEED AT YOUR OWN RISK!</string>
|
||||
<string name="discovery_need_to_enter_authkey">This device needs a secret auth key, long press on the device to enter it. Read the wiki.</string>
|
||||
<string name="maximum_duration">Duration</string>
|
||||
<string name="prefs_find_phone_duration">Ring duration in seconds</string>
|
||||
<string name="prefs_find_phone_summary">Use your band to play your phone\'s ringtone.</string>
|
||||
<string name="prefs_enable_find_phone">Turn on \\\'Find phone\\\'</string>
|
||||
<string name="prefs_find_phone">Find phone</string>
|
||||
<string name="devicetype_amazfit_bip_lite">Amazfit Bip Lite</string>
|
||||
<string name="prefs_wearside">Wearing left or right\?</string>
|
||||
<string name="devicetype_makibes_hr3">Makibes HR3</string>
|
||||
<string name="preferences_makibes_hr3_settings">Makibes HR3 settings</string>
|
||||
<string name="activity_error_no_app_for_gpx">To view activity trace, install app which can handle GPX files.</string>
|
||||
<string name="pref_display_add_device_fab_off">Visible only if no device is added</string>
|
||||
<string name="pref_display_add_device_fab_on">Always visible</string>
|
||||
<string name="pref_display_add_device_fab">Connect new device button</string>
|
||||
<string name="widget_1_hour">1 hour</string>
|
||||
<string name="widget_20_minutes">20 minutes</string>
|
||||
<string name="widget_10_minutes">10 minutes</string>
|
||||
<string name="widget_5_minutes">5 minutes</string>
|
||||
<string name="widget_set_alarm_after">Set alarm after:</string>
|
||||
<string name="widget_listing_label">Status and Alarms</string>
|
||||
<string name="widget_sleep_label">Sleep: %1$s</string>
|
||||
<string name="widget_steps_label">Steps: %1$02d</string>
|
||||
<string name="appwidget_sleep_alarm_widget_label">Sleep Alarm</string>
|
||||
<string name="activity_db_management_empty_db_warning">Warning! By pushing this button you will wipe your database and start from scratch.</string>
|
||||
<string name="activity_db_management_exportimport_label">Export and Import</string>
|
||||
<string name="activity_db_management_empty_DB">Empty Database</string>
|
||||
<string name="activity_DB_empty_button">Empty DB</string>
|
||||
<string name="activity_DB_delete_legacy_button">Delete old DB</string>
|
||||
<string name="activity_DB_test_export_message">Exporting database…</string>
|
||||
<string name="activity_DB_test_export_button">Run AutoExport Now</string>
|
||||
<string name="activity_DB_import_button">Import DB</string>
|
||||
<string name="activity_DB_ExportButton">Export DB</string>
|
||||
<string name="activity_db_management_autoexport_label">AutoExport</string>
|
||||
<string name="activity_db_management_autoexport_explanation">Database autoexport location has been set to:</string>
|
||||
<string name="pref_summary_use_custom_font">Enable this if your device has a custom font firmware for emoji support</string>
|
||||
<string name="pref_title_use_custom_font">Use custom font</string>
|
||||
<string name="pref_title_expose_hr">3rd party realtime HR access</string>
|
||||
<string name="pref_summary_expose_hr">Allows other apps to access HR data in realtime while Gadgetbridge is connected</string>
|
||||
<string name="menuitem_nfc">NFC</string>
|
||||
<string name="devicetype_mijia_lywsd02">Mijia Smart Clock</string>
|
||||
<string name="weeksleepchart_sleep_a_month">Sleep per month</string>
|
||||
<string name="weekstepschart_steps_a_month">Steps per month</string>
|
||||
<string name="pref_charts_range_off">Charts range is set to a Week</string>
|
||||
<string name="pref_charts_range_on">Charts range is set to a Month</string>
|
||||
<string name="pref_title_charts_range">Charts Range</string>
|
||||
<string name="pref_title_charts_average">Show averages in the charts</string>
|
||||
<string name="pref_header_charts">Charts Settings</string>
|
||||
<string name="average">Average: %1$s</string>
|
||||
<string name="prefs_hr_alarm_high">High limit</string>
|
||||
<string name="prefs_hr_alarm_low">Low limit</string>
|
||||
<string name="prefs_hr_alarm_activity">Heart rate alarm during sports activity</string>
|
||||
<string name="fw_upgrade_notice_miband4">You are about to install the %s firmware on your Mi Band 4.
|
||||
\n
|
||||
\nPlease make sure to install the .fw file, and after that the .res file. Your band will reboot after installing the .fw file.
|
||||
\n
|
||||
\nNote: You do not have to install .res if it is exactly the same as the one previously installed.
|
||||
\n
|
||||
\nPROCEED AT YOUR OWN RISK!</string>
|
||||
<string name="devicetype_miband4">Mi Band 4</string>
|
||||
<string name="devicetype_amazfit_cor2">Amazfit Cor 2</string>
|
||||
<string name="portuguese">Portuguese</string>
|
||||
<string name="vietnamese">Vietnamese</string>
|
||||
<string name="thai">Thai</string>
|
||||
<string name="indonesian">Indonesian</string>
|
||||
<string name="arabic">Arabic</string>
|
||||
<string name="ukrainian">Ukrainian</string>
|
||||
<string name="turkish">Turkish</string>
|
||||
<string name="dutch">Dutch</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor2">You are about to install the %s firmware on your Amazfit Cor 2.
|
||||
\n
|
||||
\nPlease make sure to install the .fw file, and after that the .res file. Your band will reboot after installing the .fw file.
|
||||
\n
|
||||
\nNote: You do not have to install .res if it is exactly the same as the one previously installed.
|
||||
\n
|
||||
\nPROCEED AT YOUR OWN RISK!
|
||||
\n
|
||||
\nCOMPLETELY UNTESTED, PROBABLY YOU NEED TO FLASH A BEATS_W FIRMWARE IF YOUR DEVICE NAME IS \"Amazfit Band 2\"</string>
|
||||
<string name="devicetype_bfh16">BFH-16</string>
|
||||
<string name="pref_summary_authkey">Change the auth key to a common key on all your Android devices from which you would like to connect from. The previous default key for all devices is 0123456789@ABCDE</string>
|
||||
<string name="pref_title_authkey">Auth Key</string>
|
||||
<string name="title_activity_device_specific_settings">Device specific settings</string>
|
||||
<string name="pref_title_support_voip_calls">Enable VoIP app calls</string>
|
||||
<string name="devicetype_miscale2">Mi Scale 2</string>
|
||||
<string name="activity_prefs_activetime_minutes">Daily target: active time in minutes</string>
|
||||
<string name="activity_prefs_calories_burnt">Daily target: calories burnt</string>
|
||||
<string name="interval_forty_five_minutes">every 45 minutes</string>
|
||||
<string name="interval_fifteen_minutes">every 15 minutes</string>
|
||||
<string name="pref_screen_notification_profile_anti_loss">Anti-loss warning</string>
|
||||
<string name="pref_screen_notification_profile_low_power">Low power warning</string>
|
||||
<string name="pref_screen_notification_profile_inactivity">Inactivity notification</string>
|
||||
<string name="pref_screen_notification_profile_calendar">Calendar notification</string>
|
||||
<string name="pref_screen_notification_profile_missed_call">Missed call notification</string>
|
||||
<string name="zetime_signaling_vibrate_beep_once">Vibrate and beep once</string>
|
||||
<string name="zetime_signaling_beep_twice">Beep twice</string>
|
||||
<string name="zetime_signaling_beep_once">Beep once</string>
|
||||
<string name="zetime_signaling_vibrate_twice">Vibrate twice</string>
|
||||
<string name="zetime_signaling_vibrate_once">Vibrate once</string>
|
||||
<string name="zetime_signaling_vibrate_beep">Continuous vibration and beeping</string>
|
||||
<string name="zetime_signaling_beep">Continuous beeping</string>
|
||||
<string name="zetime_signaling_vibrate">Continuous vibration</string>
|
||||
<string name="zetime_signaling_none">Silent</string>
|
||||
<string name="zetime_title_alarm_signaling">Set type of signaling for the alarm</string>
|
||||
<string name="zetime_prefs_inactivity_su">Sunday</string>
|
||||
<string name="zetime_prefs_inactivity_sa">Saturday</string>
|
||||
<string name="zetime_prefs_inactivity_fr">Friday</string>
|
||||
<string name="zetime_prefs_inactivity_th">Thursday</string>
|
||||
<string name="zetime_prefs_inactivity_we">Wednesday</string>
|
||||
<string name="zetime_prefs_inactivity_tu">Tuesday</string>
|
||||
<string name="zetime_prefs_inactivity_mo">Monday</string>
|
||||
<string name="zetime_prefs_inactivity_repetitions">Repetitions</string>
|
||||
<string name="zetime_date_format_3">MM/DD/YY</string>
|
||||
<string name="zetime_date_format_2">DD/MM/YY</string>
|
||||
<string name="zetime_date_format_1">YY/MM/DD</string>
|
||||
<string name="zetime_date_format">Date format</string>
|
||||
<string name="zetime_calories_type_all">Active and inactive burnt calories</string>
|
||||
<string name="zetime_calories_type_active">Only active burnt calories</string>
|
||||
<string name="zetime_calories_type">Calories type</string>
|
||||
<string name="zetime_handmove_display_summary">Rotate your wrist to activate or deactivate the display.</string>
|
||||
<string name="zetime_handmove_display">Hand movement</string>
|
||||
<string name="zetime_activity_tracking_summary">Switching the activity tracking on, will count your steps and so on.</string>
|
||||
<string name="zetime_activity_tracking">Activity tracking</string>
|
||||
<string name="zetime_analog_mode_handsandsteps">Hands and steps</string>
|
||||
<string name="zetime_analog_mode_hands">Only hands</string>
|
||||
<string name="zetime_analog_mode">Analog mode</string>
|
||||
<string name="activity_prefs_alarm_min_heart_rate">Min heart rate</string>
|
||||
<string name="activity_prefs_alarm_max_heart_rate">Max heart rate</string>
|
||||
<string name="zetime_heart_rate_alarm_enable">Enable the heart rate alarm</string>
|
||||
<string name="zetime_title_heart_rate_alarm_summary">The watch will warn you when your heart rate exceeds the limits.</string>
|
||||
<string name="zetime_title_heart_rate_alarm">Heart rate alarm</string>
|
||||
<string name="zetime_title_screentime">Screen on duration in seconds</string>
|
||||
<string name="zetime_title_heartrate">Heart rate settings</string>
|
||||
<string name="zetime_title_settings">ZeTime settings</string>
|
||||
<string name="prefs_disconnect_notification">Disconnect notification</string>
|
||||
<string name="activity_type_exercise">Exercise</string>
|
||||
<string name="appwidget_not_connected">Not connected, alarm not set.</string>
|
||||
<string name="save_configuration">Save Configuration</string>
|
||||
<string name="mode_configuration">Mode Configuration</string>
|
||||
<string name="filter_mode">Filter Mode</string>
|
||||
<string name="toast_notification_filter_words_empty_hint">Please enter at least one word</string>
|
||||
<string name="filter_submode_all">All of the words</string>
|
||||
<string name="filter_submode_at_least_one">At least one of the words</string>
|
||||
<string name="filter_mode_blacklist">Block when words are contained</string>
|
||||
<string name="filter_mode_whitelist">Show when words are contained</string>
|
||||
<string name="filter_mode_none">Do not filter</string>
|
||||
<string name="toast_notification_filter_saved_successfully">Notification filter saved</string>
|
||||
<string name="edittext_notification_filter_words_hint">Enter desired words, new line for each</string>
|
||||
<string name="toast_app_must_not_be_blacklisted">App must not be blacklisted to be configured</string>
|
||||
<string name="preferences_rtl_settings">Right To Left Support</string>
|
||||
<string name="pref_summary_contextual_arabic">Enable this to support contextual Arabic</string>
|
||||
<string name="pref_title_contextual_arabic">Contextual Arabic</string>
|
||||
<string name="pref_rtl_max_line_length_summary">Lengthens or shortens the lines Right-To-Left text is separated into</string>
|
||||
<string name="pref_rtl_max_line_length">Right-To-Left Max Line Length</string>
|
||||
<string name="pref_summary_rtl">Enable this if your device can not show right-to-left languages</string>
|
||||
<string name="pref_title_rtl">Right-To-Left</string>
|
||||
<string name="activity_prefs_chart_min_heart_rate">Min heart rate</string>
|
||||
<string name="activity_prefs_chart_max_heart_rate">Max heart rate</string>
|
||||
<string name="activity_prefs_charts">Chart settings</string>
|
||||
<string name="pref_invalid_frequency_message">Please enter a frequency between 87.5 and 108.0</string>
|
||||
<string name="pref_invalid_frequency_title">Invalid frequency</string>
|
||||
<string name="preferences_fm_frequency">FM Frequency</string>
|
||||
<string name="devicetype_roidmi3">Roidmi 3</string>
|
||||
<string name="devicetype_roidmi">Roidmi</string>
|
||||
<string name="controlcenter_change_fm_frequency">Change FM Frequency</string>
|
||||
<string name="warning">Warning!</string>
|
||||
<string name="share_log_warning">Please keep in mind Gadgetbridge logs files that may contain lots of personal info, including but not limited to health data, unique identifiers (such as a device\'s MAC address), music preferences, etc. Consider editing the file and removing this info before sending the file to a public issue report.</string>
|
||||
<string name="share_log">Share log</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="mi3_night_mode_sunset">At sunset</string>
|
||||
<string name="mi3_prefs_night_mode_summary">Lower band screen brightness automatically at night</string>
|
||||
<string name="mi3_prefs_night_mode">Night mode</string>
|
||||
<string name="minutes_30">30 minutes</string>
|
||||
<string name="minutes_10">10 minutes</string>
|
||||
<string name="minutes_5">5 minutes</string>
|
||||
<string name="minutes_1">1 minute</string>
|
||||
<string name="seconds_30">30 seconds</string>
|
||||
<string name="seconds_20">20 seconds</string>
|
||||
<string name="seconds_10">10 seconds</string>
|
||||
<string name="seconds_5">5 seconds</string>
|
||||
<string name="no_limit">No limit</string>
|
||||
<string name="pref_title_notifications_timeout">Minimum time between notifications</string>
|
||||
<string name="norwegian_bokmal">Norwegian Bokmål</string>
|
||||
<string name="you_did_not_sleep">You did not sleep</string>
|
||||
<string name="you_slept">You slept from %1$s to %2$s</string>
|
||||
<string name="japanese">Japanese</string>
|
||||
<string name="korean">Korean</string>
|
||||
<string name="polish">Polish</string>
|
||||
<string name="french">French</string>
|
||||
<string name="italian">Italian</string>
|
||||
<string name="german">German</string>
|
||||
<string name="mi3_prefs_band_screen_unlock_summary">Swipe up to unlock the band\'s screen</string>
|
||||
<string name="mi3_prefs_band_screen_unlock">Band screen unlock</string>
|
||||
<string name="title_activity_watch9_calibration">Watch 9 calibration</string>
|
||||
<string name="title_activity_watch9_pairing">Watch 9 pairing</string>
|
||||
<string name="watch9_calibration_button">Calibrate</string>
|
||||
<string name="watch9_calibration_hint">Set the time your device is showing to you right now.</string>
|
||||
<string name="watch9_time_seconds">Seconds:</string>
|
||||
<string name="watch9_time_hours">Hours:</string>
|
||||
<string name="watch9_time_minutes">Minutes:</string>
|
||||
<string name="devicetype_watch9">Watch 9</string>
|
||||
<string name="watch9_pairing_tap_hint">When your watch vibrates, shake the device or press its button.</string>
|
||||
<string name="controlcenter_calibrate_device">Calibrate Device</string>
|
||||
<string name="menuitem_music">Music</string>
|
||||
<string name="menuitem_more">More</string>
|
||||
<string name="menuitem_notifications">Notifications</string>
|
||||
<string name="devicetype_id115">ID115</string>
|
||||
<string name="vertical">Vertical</string>
|
||||
<string name="horizontal">Horizontal</string>
|
||||
<string name="prefs_screen_orientation">Screen orientation</string>
|
||||
<string name="russian">Russian</string>
|
||||
<string name="devicetype_mykronoz_zetime">MyKronoz ZeTime</string>
|
||||
<string name="pref_auto_fetch_limit_fetches_summary">Fetches every %d minutes</string>
|
||||
<string name="pref_auto_fetch_limit_fetches">Minimum time between fetches</string>
|
||||
<string name="pref_auto_fetch_summary">Fetch happens upon screen unlock. Only works if a lock mechanism is set!</string>
|
||||
<string name="pref_auto_fetch">Auto fetch activity data</string>
|
||||
<string name="whitelist_all_for_notifications">Whitelist all for notifications</string>
|
||||
<string name="blacklist_all_for_notifications">Blacklist all for notifications</string>
|
||||
<string name="devicetype_miband3">Mi Band 3</string>
|
||||
<string name="activity_prefs_distance_meters">Daily target: distance in metres</string>
|
||||
<string name="mi2_prefs_button_press_broadcast_summary">Broadcast message sent with the event. Parameter ‘button_id’ is added automatically to each message.</string>
|
||||
<string name="preferences_led_color">LED colour</string>
|
||||
<string name="fw_upgrade_notice_miband3">You are about to install the %s firmware on your Mi Band 3.
|
||||
\n
|
||||
\nPlease make sure to install the .fw file, and after that the .res file. Your band will reboot after installing the .fw file.
|
||||
\n
|
||||
\nNote: You do not have to install .res if it is exactly the same as the one previously installed.
|
||||
\n
|
||||
\nPROCEED AT YOUR OWN RISK!</string>
|
||||
<string name="devicetype_q8">Q8</string>
|
||||
<string name="menuitem_shortcut_weather">Weather (Shortcut)</string>
|
||||
<string name="menuitem_shortcut_alipay">Alipay (Shortcut)</string>
|
||||
<string name="pref_summary_pebble_gatt_clientonly">This is for Pebble 2 only and experimental, try this if you have connectivity problems</string>
|
||||
<string name="pref_title_pebble_gatt_clientonly">GATT client only</string>
|
||||
<string name="menuitem_alipay">Alipay</string>
|
||||
<string name="menuitem_settings">Settings</string>
|
||||
<string name="menuitem_compass">Compass</string>
|
||||
<string name="menuitem_timer">Timer</string>
|
||||
<string name="menuitem_alarm">Alarm</string>
|
||||
<string name="menuitem_weather">Weather</string>
|
||||
<string name="menuitem_activity">Activity</string>
|
||||
<string name="menuitem_status">Status</string>
|
||||
<string name="reset_index">Reset fetch date</string>
|
||||
<string name="share">Share</string>
|
||||
<string name="select_all">Select all</string>
|
||||
<string name="pref_title_audio_player">Preferred Audioplayer</string>
|
||||
<string name="pref_title_general_autoreconnect">Reconnect automatically</string>
|
||||
<string name="activity_type_treadmill">Treadmill</string>
|
||||
<string name="activity_type_biking">Biking</string>
|
||||
<string name="activity_summaries">Activities</string>
|
||||
<string name="activity_type_unknown">Unknown activity</string>
|
||||
<string name="activity_type_swimming">Swimming</string>
|
||||
<string name="activity_type_walking">Walking</string>
|
||||
<string name="activity_type_running">Running</string>
|
||||
<string name="activity_type_not_worn">Device not worn</string>
|
||||
<string name="activity_type_deep_sleep">Deep sleep</string>
|
||||
<string name="activity_type_light_sleep">Light sleep</string>
|
||||
<string name="activity_type_activity">Activity</string>
|
||||
<string name="activity_type_not_measured">Not measured</string>
|
||||
<string name="controlcenter_start_activity_tracks">Your activity tracks</string>
|
||||
<string name="on">On</string>
|
||||
<string name="devicetype_xwatch">XWatch</string>
|
||||
<string name="notification_channel_name">Gadgetbridge notifications</string>
|
||||
<string name="spanish">Spanish</string>
|
||||
<string name="choose_auto_export_location">Choose export location</string>
|
||||
<string name="notif_export_failed_title">Export database failed! Please check your settings.</string>
|
||||
<string name="pref_summary_auto_export_interval">Export every %d hour</string>
|
||||
<string name="pref_title_auto_export_interval">Export interval</string>
|
||||
<string name="pref_title_auto_export_location">Export location</string>
|
||||
<string name="pref_title_auto_export_enabled">Auto export enabled</string>
|
||||
<string name="pref_header_auto_export">Auto export</string>
|
||||
<string name="pref_title_weather">Weather</string>
|
||||
<string name="devicetype_teclast_h30">Teclast H30</string>
|
||||
<string name="devicetype_no1_f1">No.1 F1</string>
|
||||
<string name="devicetype_exrizu_k8">Exrizu K8</string>
|
||||
<string name="devicetype_makibes_f68">Makibes F68</string>
|
||||
<string name="devicetype_hplus">HPlus</string>
|
||||
<string name="devicetype_liveview">LiveView</string>
|
||||
<string name="devicetype_vibratissimo">Vibratissimo</string>
|
||||
<string name="devicetype_amazfit_cor">Amazfit Cor</string>
|
||||
<string name="devicetype_amazfit_bip">Amazfit Bip</string>
|
||||
<string name="devicetype_miband2">Mi Band 2</string>
|
||||
<string name="devicetype_miband">Mi Band</string>
|
||||
<string name="devicetype_pebble">Pebble</string>
|
||||
<string name="devicetype_test">Test Device</string>
|
||||
<string name="devicetype_unknown">Unknown Device</string>
|
||||
<string name="kind_watchface">Watchface</string>
|
||||
<string name="kind_resources">Resources</string>
|
||||
<string name="kind_gps_cep">GPS Error Correction</string>
|
||||
<string name="kind_gps_almanac">GPS Almanac</string>
|
||||
<string name="kind_gps">GPS Firmware</string>
|
||||
<string name="kind_font">Font</string>
|
||||
<string name="kind_invalid">Invalid data</string>
|
||||
<string name="kind_firmware">Firmware</string>
|
||||
<string name="pref_title_weather_location">Weather location (CM/LOS)</string>
|
||||
<string name="interval_one_hour">once an hour</string>
|
||||
<string name="interval_thirty_minutes">every 30 minutes</string>
|
||||
<string name="interval_ten_minutes">every 10 minutes</string>
|
||||
<string name="interval_five_minutes">every 5 minutes</string>
|
||||
<string name="interval_one_minute">once a minute</string>
|
||||
<string name="prefs_title_heartrate_measurement_interval">Whole day HR measurement</string>
|
||||
<string name="english">English</string>
|
||||
<string name="traditional_chinese">Traditional Chinese</string>
|
||||
<string name="simplified_chinese">Simplified Chinese</string>
|
||||
<string name="automatic">Automatic</string>
|
||||
<string name="pref_title_charts_swipe">Enable left/right swipe in the charts activity</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor">You are about to install the %s firmware on your Amazfit Cor.
|
||||
\n
|
||||
\nPlease make sure to install the .fw file, and after that the .res file. Your band will reboot after installing the .fw file.
|
||||
\n
|
||||
\nNote: You do not have to install .res if it is exactly the same as the one previously installed.
|
||||
\n
|
||||
\nPROCEED AT YOUR OWN RISK!</string>
|
||||
<string name="controlcenter_connect">Connect…</string>
|
||||
<string name="activity_web_view">Web View Activity</string>
|
||||
<string name="pref_summary_pebble_enable_bgjs">When enabled, allows watchfaces to show weather, battery info etc.</string>
|
||||
<string name="pref_title_pebble_enable_bgjs">Enable background JS</string>
|
||||
<string name="_pebble_watch_reply">Reply</string>
|
||||
<string name="_pebble_watch_mute">Mute</string>
|
||||
<string name="_pebble_watch_open_on_phone">Open on Android device</string>
|
||||
<string name="mi2_prefs_button_press_count_max_delay_summary">Maximum delay between button presses in milliseconds</string>
|
||||
<string name="mi2_prefs_button_press_count_max_delay">Maximum delay between presses</string>
|
||||
<string name="mi2_prefs_button_action_vibrate_summary">Enable band vibration on button action triggered</string>
|
||||
<string name="mi2_prefs_button_action_vibrate">Enable band vibration</string>
|
||||
<string name="mi2_prefs_button_action_summary">Enable action on specified number of button presses</string>
|
||||
<string name="mi2_prefs_button_action">Enable button action</string>
|
||||
<string name="mi2_prefs_button_press_broadcast">Broadcast message to send</string>
|
||||
<string name="mi2_prefs_button_press_count_summary">Number of button presses to trigger an Event 1. Subsequent same amount of presses create Event 2 and so on.</string>
|
||||
<string name="mi2_prefs_button_press_count">Button press count</string>
|
||||
<string name="mi2_prefs_button_actions_summary">Specify button press actions</string>
|
||||
<string name="mi2_prefs_button_actions">Button actions</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip">You are about to install the %s firmware on your Amazfit Bip.
|
||||
\n
|
||||
\nPlease make sure to install the .fw file, then the .res file, and finally the .gps file. Your watch will reboot after installing the .fw file.
|
||||
\n
|
||||
\nNote: You do not have to install .res and .gps if these files are exactly the same as the ones previously installed.
|
||||
\n
|
||||
\nPROCEED AT YOUR OWN RISK!</string>
|
||||
<string name="discovery_dont_pair">Don\'t Pair</string>
|
||||
<string name="discovery_yes_pair">Pair</string>
|
||||
<string name="discovery_pair_question">Select Pair to pair your devices. If this fails, try again without pairing.</string>
|
||||
<string name="discovery_pair_title">Pair with %1$s\?</string>
|
||||
<string name="discovery_successfully_bonded">Bound to %1$s.</string>
|
||||
<string name="discovery_enable_bluetooth">Enable Bluetooth to discover devices.</string>
|
||||
<string name="discovery_trying_to_connect_to">Trying to connect to: %1$s</string>
|
||||
<string name="discovery_bonding_failed_immediately">Bonding with %1$s failed immediately.</string>
|
||||
<string name="discovery_attempting_to_pair">Attempting to pair with %1$s</string>
|
||||
<string name="mi2_dnd_scheduled">Scheduled (time interval)</string>
|
||||
<string name="mi2_dnd_automatic">Automatic (sleep detection)</string>
|
||||
<string name="mi2_dnd_off">Off</string>
|
||||
<string name="off">Off</string>
|
||||
<string name="mi2_enable_text_notifications_summary">Needs firmware >= 1.0.1.28 and Mili_pro.ft* installed.</string>
|
||||
<string name="mi2_enable_text_notifications">Text notifications</string>
|
||||
<string name="mi2_fw_installhandler_fw53_hint">You need to install version %1$s before installing this firmware!</string>
|
||||
<string name="miband2_prefs_timeformat">Mi2: Time format</string>
|
||||
<string name="find_device_you_found_it">You found it!</string>
|
||||
<string name="StringUtils_sender">(%1$s)</string>
|
||||
<string name="pref_screen_notification_profile_alarm_clock">Alarm clock</string>
|
||||
<string name="timeformat_am_pm">AM/PM</string>
|
||||
<string name="timeformat_24h">24H</string>
|
||||
<string name="unit_imperial">Imperial</string>
|
||||
<string name="unit_metric">Metric</string>
|
||||
<string name="pref_summary_setup_bt_pairing">Deactivate this if you have trouble connecting</string>
|
||||
<string name="pref_title_setup_bt_pairing">Enable Bluetooth pairing</string>
|
||||
<string name="weather_notification_label">Make sure that this skin is enabled in the Weather Notification app to get weather information on your Pebble.
|
||||
\n
|
||||
\nNo configuration is needed here.
|
||||
\n
|
||||
\nYou can enable the system weather app of your Pebble from the app management.
|
||||
\n
|
||||
\nSupported watchfaces will show the weather automatically.</string>
|
||||
<string name="pebble_pairing_hint">A pairing dialog will pop up on your Android device. If not, look in the notification drawer and accept the pairing request. Also accept it on your Pebble afterwards.</string>
|
||||
<string name="title_activity_pebble_pairing">Pebble pairing</string>
|
||||
<string name="title_activity_vibration">Vibration</string>
|
||||
<string name="Delete">Delete</string>
|
||||
<string name="Cancel">Cancel</string>
|
||||
<string name="dbmanagementactivity_overwrite">Overwrite</string>
|
||||
<string name="dbmanagementactivity_old_activity_db_deletion_failed">Old Activity database deletion failed.</string>
|
||||
<string name="dbmanagementactivity_old_activity_db_successfully_deleted">Old activity data deleted.</string>
|
||||
<string name="dbmanagementactivity_delete_old_activitydb_confirmation">Really delete the old activity database\? Activity data that was not imported will be lost.</string>
|
||||
<string name="dbmanagementactivity_delete_old_activity_db">Delete old Activity Database\?</string>
|
||||
<string name="dbmanagementactivity_db_deletion_failed">Database deletion failed.</string>
|
||||
<string name="dbmanagementactivity_database_successfully_deleted">Data deleted.</string>
|
||||
<string name="dbmanagementactivity_really_delete_entire_db">Really delete the entire database\? All your activity data and information about your devices will be lost.</string>
|
||||
<string name="dbmanagementactivity_delete_activity_data_title">Delete Activity Data\?</string>
|
||||
<string name="dbmanagementactivity_error_importing_shared">Error importing preference: %1$s</string>
|
||||
<string name="dbmanagementactivity_error_importing_db">Error importing DB: %1$s</string>
|
||||
<string name="dbmanagementactivity_import_successful">Imported.</string>
|
||||
<string name="dbmanagementactivity_overwrite_database_confirmation">Really overwrite the current database\? All your current activity data (if any) will be lost.</string>
|
||||
<string name="pref_summary_pebble_health_store_raw">Stores the data \"as is\", increasing the database usage to allow for later interpretation.</string>
|
||||
<string name="pref_title_pebble_health_store_raw">Store raw record in the database</string>
|
||||
<string name="live_activity_heart_rate">Heart rate</string>
|
||||
<string name="charts_legend_heartrate">Heart rate</string>
|
||||
<string name="updatefirmwareoperation_firmware_not_sent">Firmware not sent</string>
|
||||
<string name="updatefirmwareoperation_update_in_progress">Flashing firmware</string>
|
||||
<string name="DEVINFO_HR_VER">"HR: "</string>
|
||||
<string name="error_creating_directory_for_logfiles">Error creating directory for log files: %1$s</string>
|
||||
<string name="device_fw">Firmware version: %1$s</string>
|
||||
<string name="device_hw">Hardware revision: %1$s</string>
|
||||
<string name="activity_prefs_sleep_duration">Preferred sleep duration in hours</string>
|
||||
<string name="add_widget">Add widget</string>
|
||||
<string name="appwidget_text">Zzz</string>
|
||||
<string name="authentication_required">Authentication required</string>
|
||||
<string name="authenticating">Authenticating</string>
|
||||
<string name="activity_prefs_weight_kg">Weight in kg</string>
|
||||
<string name="activity_prefs_height_cm">Height in cm</string>
|
||||
<string name="activity_prefs_gender">Gender</string>
|
||||
<string name="activity_prefs_year_birth">Year of birth</string>
|
||||
<string name="activity_prefs_about_you">About you</string>
|
||||
<string name="waiting_for_reconnect">Waiting for reconnect</string>
|
||||
<string name="FetchActivityOperation_about_to_transfer_since">About to transfer data since %1$s</string>
|
||||
<string name="mi2_prefs_do_not_disturb_end">End time</string>
|
||||
<string name="mi2_prefs_do_not_disturb_start">Start time</string>
|
||||
<string name="mi2_prefs_inactivity_warnings_dnd_summary">Disable inactivity warnings for a time interval</string>
|
||||
<string name="mi2_prefs_inactivity_warnings_threshold">Inactivity threshold (in minutes)</string>
|
||||
<string name="mi2_prefs_inactivity_warnings_summary">The band will vibrate when you have been inactive for a while</string>
|
||||
<string name="mi2_prefs_inactivity_warnings">Inactivity warnings</string>
|
||||
<string name="mi2_prefs_do_not_disturb_summary">The band won\'t receive notifications while active</string>
|
||||
<string name="mi2_prefs_do_not_disturb">Do Not Disturb</string>
|
||||
<string name="mi2_prefs_rotate_wrist_to_switch_info">Rotate wrist to switch info</string>
|
||||
<string name="mi2_prefs_activate_display_on_lift">Activate display upon lift</string>
|
||||
<string name="mi2_prefs_display_items_summary">Choose the items displayed on the band screen</string>
|
||||
<string name="mi2_prefs_display_items">Display items</string>
|
||||
<string name="mi2_prefs_goal_notification_summary">The band will vibrate when the daily steps goal is reached</string>
|
||||
<string name="mi2_prefs_goal_notification">Goal notification</string>
|
||||
<string name="dateformat_date_time">Time & date</string>
|
||||
<string name="dateformat_time">Time</string>
|
||||
<string name="miband2_prefs_dateformat">Date format</string>
|
||||
<string name="miband_prefs_device_time_offset_hours">Device time offset in hours (for detecting sleep of shift workers)</string>
|
||||
<string name="miband_prefs_hr_sleep_detection">Use heart rate sensor to improve sleep detection</string>
|
||||
<string name="miband_prefs_reserve_alarm_calendar">Alarms to reserve for upcoming events</string>
|
||||
<string name="fwinstaller_firmware_not_compatible_to_device">This firmware is not compatible with the device</string>
|
||||
<string name="miband_fwinstaller_incompatible_version">Incompatible firmware</string>
|
||||
<string name="pref_title_keep_data_on_device">Keep activity data on device</string>
|
||||
<string name="user_feedback_all_alarms_disabled">All alarms disabled</string>
|
||||
<string name="device_not_connected">Not connected.</string>
|
||||
<string name="abstract_chart_fragment_kind_not_worn">Not worn</string>
|
||||
<string name="abstract_chart_fragment_kind_deep_sleep">Deep sleep</string>
|
||||
<string name="abstract_chart_fragment_kind_light_sleep">Light sleep</string>
|
||||
<string name="abstract_chart_fragment_kind_activity">Activity</string>
|
||||
<string name="live_activity_start_your_activity">Start your activity</string>
|
||||
<string name="live_activity_steps_per_minute_history">Steps per minute history</string>
|
||||
<string name="live_activity_total_steps">Total steps</string>
|
||||
<string name="live_activity_current_steps_per_minute">Current steps/min</string>
|
||||
<string name="live_activity_steps_history">Steps history</string>
|
||||
<string name="pref_summary_low_latency_fw_update">This might help on devices where firmware flashing fails.</string>
|
||||
<string name="pref_title_low_latency_fw_update">Use low-latency mode for firmware flashing</string>
|
||||
<string name="pref_summary_keep_data_on_device">Will keep activity data on the Mi Band even after synchronization. Useful if GB is used together with other apps.</string>
|
||||
<string name="pref_summary_dont_ack_transfers">If the activity data are not acked to the band, they will not be cleared. Useful if GB is used together with other apps.</string>
|
||||
<string name="pref_title_dont_ack_transfer">Do not ACK activity data transfer</string>
|
||||
<string name="weeksteps_today_steps_description">Steps today, target: %1$s</string>
|
||||
<string name="liveactivity_live_activity">Live activity</string>
|
||||
<string name="battery">Battery</string>
|
||||
<string name="heart_rate">Heart rate</string>
|
||||
<string name="clock">Clock</string>
|
||||
<string name="distance">Distance</string>
|
||||
<string name="calories">Calories</string>
|
||||
<string name="chart_steps">Steps</string>
|
||||
<string name="updatefirmwareoperation_write_failed">Firmware flashing failed</string>
|
||||
<string name="updatefirmwareoperation_update_complete_rebooting">Firmware installation complete, rebooting device…</string>
|
||||
<string name="updatefirmwareoperation_update_complete">Firmware installation complete</string>
|
||||
<string name="title_activity_notification_filter">Notification Filter</string>
|
||||
<string name="appwidget_setting_alarm">Setting alarm for %1$02d:%2$02d</string>
|
||||
<string name="devicetype_casiogb6900">Casio GB-6900</string>
|
||||
<string name="debugactivity_really_factoryreset">Doing a factory reset will delete all data from the connected device (if supported). Xiaomi/Huami devices also change Bluetooth MAC address, so they appear as a new devices to Gadgetbridge.</string>
|
||||
<string name="debugactivity_really_factoryreset_title">Really factory reset\?</string>
|
||||
<string name="live_activity_max_heart_rate">Current / Max heart rate: %1$d / %2$d</string>
|
||||
<string name="no_data">No data</string>
|
||||
<string name="overstep">Overstep: %1$d</string>
|
||||
<string name="lack_of_step">Lack of steps: %1$d</string>
|
||||
<string name="overslept">Overslept: %1$s</string>
|
||||
<string name="lack_of_sleep">Lack of sleep: %1$s</string>
|
||||
<string name="language_and_region_prefs">Language and region settings</string>
|
||||
<string name="updatefirmwareoperation_metadata_updateproblem">Problem with the firmware metadata transfer</string>
|
||||
<string name="updatefirmwareoperation_updateproblem_do_not_reboot">Problem with the firmware transfer. DO NOT REBOOT your Mi Band!</string>
|
||||
<string name="pbwinstallhandler_incorrect_hw_revision">Hardware revision mismatch!</string>
|
||||
<string name="pbwinstallhandler_correct_hw_revision">Correct hardware revision</string>
|
||||
<string name="pbw_installhandler_pebble_firmware">Pebble Firmware %1$s</string>
|
||||
<string name="fwappinstaller_connection_state">Connection to device: %1$s</string>
|
||||
<string name="miband_fwinstaller_untested_version">Untested version!</string>
|
||||
<string name="miband_fwinstaller_compatible_version">Compatible version</string>
|
||||
<string name="fwapp_install_device_not_ready">File cannot be installed, device not ready.</string>
|
||||
<string name="updating_firmware">Flashing firmware…</string>
|
||||
<string name="activity_sleepchart_activity_and_sleep">Activity</string>
|
||||
<string name="weekstepschart_steps_a_week">Steps per week</string>
|
||||
<string name="weeksleepchart_today_sleep_description">Sleep today, target: %1$s</string>
|
||||
<string name="weeksleepchart_sleep_a_week">Sleep per week</string>
|
||||
<string name="sleepchart_your_sleep">Sleep</string>
|
||||
<string name="notif_battery_low_bigtext_number_of_charges">Number of charges: %s</string>
|
||||
<string name="notif_battery_low_bigtext_last_charge_time">Last charge: %s
|
||||
\n</string>
|
||||
<string name="notif_battery_low_title">Gadget battery Low!</string>
|
||||
<string name="installer_activity_wait_while_determining_status">Please wait while determining the installation status…</string>
|
||||
<string name="pbw_install_handler_hw_revision_mismatch">Unable to install the given firmware: It doesn\'t match your Pebble\'s hardware revision.</string>
|
||||
<string name="pbw_install_handler_unable_to_install">Unable to install the given file: %1$s</string>
|
||||
<string name="installer_activity_unable_to_find_handler">Unable to find a handler to install this file.</string>
|
||||
<string name="cannot_connect">Cannot connect: %1$s</string>
|
||||
<string name="controlcenter_start_activitymonitor">Your activity (ALPHA)</string>
|
||||
<string name="dbaccess_error_executing">Error executing \'%1$s\'</string>
|
||||
<string name="miband_prefs_fitness_goal">Daily step target</string>
|
||||
<string name="user_feedback_miband_activity_data_transfer">About to transfer %1$s of data starting from %2$s</string>
|
||||
<string name="chart_no_data_synchronize">No data. Synchronize device\?</string>
|
||||
<string name="user_feedback_miband_set_alarms_ok">Alarms sent to device.</string>
|
||||
<string name="user_feedback_miband_set_alarms_failed">There was an error setting the alarms, please try again.</string>
|
||||
<string name="alarm_smart_wakeup">Smart wakeup</string>
|
||||
<string name="alarm_sat_short">Sat</string>
|
||||
<string name="alarm_fri_short">Fri</string>
|
||||
<string name="alarm_thu_short">Thu</string>
|
||||
<string name="alarm_wed_short">Wed</string>
|
||||
<string name="alarm_tue_short">Tue</string>
|
||||
<string name="alarm_mon_short">Mon</string>
|
||||
<string name="alarm_sun_short">Sun</string>
|
||||
<string name="title_activity_alarm_details">Alarm details</string>
|
||||
<string name="controlcenter_start_configure_alarms">Configure alarms</string>
|
||||
<string name="title_activity_set_alarm">Configure alarms</string>
|
||||
<string name="title_activity_charts">Activity and Sleep</string>
|
||||
<string name="control_center_cancel_to_stop_vibration">Cancel to stop vibration.</string>
|
||||
<string name="control_center_find_lost_device">Find lost device</string>
|
||||
<string name="stats_y_axis_label">Steps per minute</string>
|
||||
<string name="stats_x_axis_label">Total minutes</string>
|
||||
<string name="stats_title">Speed zones</string>
|
||||
<string name="pref_screen_notification_profile_generic_social">Social network</string>
|
||||
<string name="pref_screen_notification_profile_generic_navigation">Navigation</string>
|
||||
<string name="pref_screen_notification_profile_generic_chat">Chat</string>
|
||||
<string name="pref_screen_notification_profile_incoming_call">Incoming call notification</string>
|
||||
<string name="pref_screen_notification_profile_email">E-mail notification</string>
|
||||
<string name="pref_screen_notification_profile_generic">Generic notification</string>
|
||||
<string name="pref_header_vibration_settings">Vibration settings</string>
|
||||
<string name="pref_screen_notification_profile_sms">SMS notification</string>
|
||||
<string name="vibration_try">Try</string>
|
||||
<string name="miband_prefs_vibration">Vibration</string>
|
||||
<string name="vibration_profile_alarm_clock">Alarm clock</string>
|
||||
<string name="vibration_profile_ring">Ring</string>
|
||||
<string name="vibration_profile_waterdrop">Waterdrop</string>
|
||||
<string name="vibration_profile_long">Long</string>
|
||||
<string name="vibration_profile_medium">Medium</string>
|
||||
<string name="vibration_profile_short">Short</string>
|
||||
<string name="vibration_profile_staccato">Staccato</string>
|
||||
<string name="pref_screen_vibration_profile">Vibration profile</string>
|
||||
<string name="sleep_activity_date_range">From %1$s to %2$s</string>
|
||||
<string name="busy_task_fetch_activity_data">Fetching activity data</string>
|
||||
<string name="initializing">Initializing</string>
|
||||
<string name="pref_write_logfiles">Write log files</string>
|
||||
<string name="title_activity_sleepmonitor">Sleep monitor</string>
|
||||
<string name="pref_header_vibration_count">Vibration count</string>
|
||||
<string name="miband_prefs_alias">Name/Alias</string>
|
||||
<string name="candidate_item_device_image">Device image</string>
|
||||
<string name="discovery_note">Note:</string>
|
||||
<string name="discovery_connected_devices_hint">Make your device discoverable. Currently connected devices will likely not be discovered. Activate location (e.g. GPS) on Android 6+. Disable Privacy Guard for Gadgetbridge, because it may crash and reboot your phone. If no device is found after a few minutes, try again after rebooting your mobile device.</string>
|
||||
<string name="appinstaller_install">Install</string>
|
||||
<string name="miband_pairing_tap_hint">When your Mi Band vibrates and blinks, tap it a few times in a row.</string>
|
||||
<string name="miband_pairing_using_dummy_userdata">No valid user data given, using dummy user data for now.</string>
|
||||
<string name="right">Right</string>
|
||||
<string name="left">Left</string>
|
||||
<string name="other">Other</string>
|
||||
<string name="female">Female</string>
|
||||
<string name="male">Male</string>
|
||||
<string name="preferences_miband_settings">Mi Band / Amazfit settings</string>
|
||||
<string name="preferences_category_device_specific_settings">Device specific settings</string>
|
||||
<string name="message_cannot_pair_no_mac">No MAC address passed, cannot pair.</string>
|
||||
<string name="pairing_already_bonded">Already bonded with %1$s (%2$s), connecting…</string>
|
||||
<string name="pairing_in_progress">Bonding in progress: %1$s (%2$s)</string>
|
||||
<string name="pairing_unable_to_pair_with">Unable to pair with %1$s (%2$s)</string>
|
||||
<string name="pairing_creating_bond_with">Creating bond with %1$s (%2$s)</string>
|
||||
<string name="pairing">Pairing with %s…</string>
|
||||
<string name="title_activity_mi_band_pairing">Pair your Mi Band</string>
|
||||
<string name="android_pairing_hint">Use the Android Bluetooth pairing dialog to pair the device.</string>
|
||||
<string name="title_activity_android_pairing">Pair device</string>
|
||||
<string name="action_discover">Connect new device</string>
|
||||
<string name="discovery_start_scanning">Start discovery</string>
|
||||
<string name="discovery_stop_scanning">Stop scanning</string>
|
||||
<string name="title_activity_discovery">Device discovery</string>
|
||||
<string name="initialized">initialized</string>
|
||||
<string name="n_a">N/A</string>
|
||||
<string name="app_install_info">You are about to install the following app:
|
||||
\n
|
||||
\n
|
||||
\n%1$s Version %2$s by %3$s
|
||||
\n</string>
|
||||
<string name="firmware_install_warning">YOU ARE TRYING TO INSTALL A FIRMWARE, PROCEED AT YOUR OWN RISK.
|
||||
\n
|
||||
\n
|
||||
\n This firmware is for HW Revision: %s</string>
|
||||
<string name="installation_successful">Installed</string>
|
||||
<string name="installation_failed_">Installation failed</string>
|
||||
<string name="installing_binary_d_d">Installing binary %1$d/%2$d</string>
|
||||
<string name="gadgetbridge_running">Gadgetbridge running</string>
|
||||
<string name="cannot_connect_bt_address_invalid_">Cannot connect. Bluetooth address invalid\?</string>
|
||||
<string name="tap_a_device_to_connect">Tap a device to connect</string>
|
||||
<string name="tap_connected_device_for_vibration">Tap connected device for vibration</string>
|
||||
<string name="tap_connected_device_for_activity">Tap connected device for activity</string>
|
||||
<string name="tap_connected_device_for_app_mananger">Tap connected device for App manager</string>
|
||||
<string name="bluetooth_is_disabled_">Bluetooth is disabled.</string>
|
||||
<string name="bluetooth_is_not_supported_">Bluetooth is not supported.</string>
|
||||
<string name="this_is_a_test_notification_from_gadgetbridge">This is a test notification from Gadgetbridge</string>
|
||||
<string name="test_notification">Test notification</string>
|
||||
<string name="test">Test</string>
|
||||
<string name="_unknown_">(unknown)</string>
|
||||
<string name="unknown_state">Unknown state</string>
|
||||
<string name="connected">Connected</string>
|
||||
<string name="connecting">Connecting</string>
|
||||
<string name="not_connected">Not connected</string>
|
||||
<string name="preferences_hplus_settings">HPlus/Makibes settings</string>
|
||||
<string name="prefs_title_all_day_heart_rate">All day heart rate measurement</string>
|
||||
<string name="pref_title_screentime">Screen on duration</string>
|
||||
<string name="pref_title_timeformat">Time format</string>
|
||||
<string name="pref_title_unit_system">Units</string>
|
||||
<string name="pref_title_pebble_reconnect_attempts">Reconnection attempts</string>
|
||||
<string name="pref_summary_pebble_always_ack_pebblekit">Will cause messages that are sent to external 3rd party apps to be acknowledged always and immediately</string>
|
||||
<string name="pref_title_pebble_always_ack_pebblekit">Prematurely ACK PebbleKit</string>
|
||||
<string name="pref_summary_pebble_enable_applogs">Will cause logs from watch apps to be logged by Gadgetbridge (requires reconnect)</string>
|
||||
<string name="pref_title_pebble_enable_applogs">Enable watch app logging</string>
|
||||
<string name="pref_summary_pebble_mtu_limit">If your Pebble 2/Pebble LE does not work as expected, try this setting to limit the MTU (valid range 20–512)</string>
|
||||
<string name="pref_title_pebble_mtu_limit">Pebble 2/LE GATT MTU limit</string>
|
||||
<string name="pref_summary_pebble_forcele">Use experimental Pebble LE support for all Pebbles, instead of BT classic. This requires pairing to non LE first, and then Pebble LE</string>
|
||||
<string name="pref_title_pebble_forcele">Always prefer BLE</string>
|
||||
<string name="pref_summary_pebble_forceuntested">Enable untested features. KNOW WHAT YOU ARE DOING!</string>
|
||||
<string name="pref_title_pebble_forceuntested">Enable untested features</string>
|
||||
<string name="pref_summary_pebble_forceprotocol">This option forces using the latest notification protocol depending on the firmware version. KNOW WHAT YOU ARE DOING!</string>
|
||||
<string name="pref_title_pebble_forceprotocol">Force notification protocol</string>
|
||||
<string name="toast_aqurired_networklocation">location acquired</string>
|
||||
<string name="toast_enable_networklocationprovider">Please enable network location</string>
|
||||
<string name="pref_summary_location_keep_uptodate">Try to get the current location at runtime, use the stored location as fallback</string>
|
||||
<string name="pref_title_location_keep_uptodate">Keep location updated</string>
|
||||
<string name="pref_title_location_longitude">Longitude</string>
|
||||
<string name="pref_title_location_latitude">Latitude</string>
|
||||
<string name="pref_title_location_aquire">Acquire location</string>
|
||||
<string name="pref_header_location">Location</string>
|
||||
<string name="pref_pebble_privacy_mode_complete">Show only the notification icon</string>
|
||||
<string name="pref_pebble_privacy_mode_content">Shift the notification text off-screen</string>
|
||||
<string name="pref_pebble_privacy_mode_off">Normal notifications</string>
|
||||
<string name="pref_title_pebble_privacy_mode">Privacy mode</string>
|
||||
<string name="pref_summary_autoremove_notifications">Notifications are automatically removed from the Pebble when dismissed from the Android device</string>
|
||||
<string name="pref_title_autoremove_notifications">Autoremove dismissed notifications</string>
|
||||
<string name="pref_summary_enable_calendar_sync">Send calendar events to the timeline</string>
|
||||
<string name="pref_title_enable_calendar_sync">Sync calendar</string>
|
||||
<string name="pref_summary_sunrise_sunset">Send sunrise and sunset times based on the location to the Pebble timeline</string>
|
||||
<string name="pref_title_sunrise_sunset">Sunrise and sunset</string>
|
||||
<string name="pref_header_pebble_timeline">Pebble timeline</string>
|
||||
<string name="pref_summary_enable_pebblekit">Enable experimental support for Android apps using PebbleKit</string>
|
||||
<string name="pref_title_enable_pebblekit">Allow 3rd party Android App access</string>
|
||||
<string name="pref_summary_enable_outgoing_call">Disabling this will also stop the Pebble 2/LE to vibrate on outgoing calls</string>
|
||||
<string name="pref_title_enable_outgoing_call">Support outgoing calls</string>
|
||||
<string name="pref_title_pebble_sync_morpheuz">Sync Morpheuz</string>
|
||||
<string name="pref_title_pebble_sync_misfit">Sync Misfit</string>
|
||||
<string name="pref_title_pebble_sync_health">Sync Pebble Health</string>
|
||||
<string name="pref_title_pebble_activitytracker">Preferred activity tracker</string>
|
||||
<string name="pref_header_activitytrackers">Activity trackers</string>
|
||||
<string name="pref_title_pebble_settings">Pebble settings</string>
|
||||
<string name="pref_title_development_miaddr">Mi Band address</string>
|
||||
<string name="pref_header_development">Developer options</string>
|
||||
<string name="pref_title_canned_messages_set">Update on Pebble</string>
|
||||
<string name="pref_title_canned_messages_dismisscall">Call Dismissal</string>
|
||||
<string name="pref_title_canned_reply_suffix">Common suffix</string>
|
||||
<string name="pref_title_canned_replies">Replies</string>
|
||||
<string name="pref_header_cannned_messages">Canned messages</string>
|
||||
<string name="pref_blacklist_calendars">Blacklist Calendars</string>
|
||||
<string name="pref_blacklist">Blacklist Apps</string>
|
||||
<string name="pref_call_privacy_mode_complete">Hide name and number</string>
|
||||
<string name="pref_call_privacy_mode_number">Hide number but display name</string>
|
||||
<string name="pref_call_privacy_mode_name">Hide name but display number</string>
|
||||
<string name="pref_call_privacy_mode_off">Display name and number</string>
|
||||
<string name="pref_title_call_privacy_mode">Call privacy mode</string>
|
||||
<string name="pref_header_privacy">Privacy</string>
|
||||
<string name="never">Never</string>
|
||||
<string name="when_screen_off">When screen is off</string>
|
||||
<string name="always">Always</string>
|
||||
<string name="pref_summary_transliteration">Enable this if your device has no support for your language\'s font</string>
|
||||
<string name="pref_title_transliteration">Transliteration</string>
|
||||
<string name="pref_summary_notification_filter">Unwanted notifications are stopped in this mode</string>
|
||||
<string name="pref_title_notification_filter">Do Not Disturb</string>
|
||||
<string name="pref_title_whenscreenon">…also when screen is on</string>
|
||||
<string name="pref_title_notifications_generic">Generic notification support</string>
|
||||
<string name="pref_summary_notifications_pebblemsg">Support for apps that send notifications to the Pebble via PebbleKit.</string>
|
||||
<string name="pref_title_notifications_pebblemsg">Pebble Messages</string>
|
||||
<string name="pref_title_notifications_sms">SMS</string>
|
||||
<string name="pref_title_notifications_call">Phone Calls</string>
|
||||
<string name="pref_title_notifications_repetitions">Repetitions</string>
|
||||
<string name="pref_header_notifications">Notifications</string>
|
||||
<string name="pref_summary_minimize_priority_on">The icon in the status bar and the notification in the lockscreen are hidden</string>
|
||||
<string name="pref_summary_minimize_priority_off">The icon in the status bar and the notification in the lockscreen are shown</string>
|
||||
<string name="pref_title_minimize_priority">Hide the Gadgetbridge notification</string>
|
||||
<string name="pref_title_language">Language</string>
|
||||
<string name="pref_theme_dark">Dark</string>
|
||||
<string name="pref_theme_light">Light</string>
|
||||
<string name="pref_title_theme">Theme</string>
|
||||
<string name="pref_summary_datetime_syctimeonconnect">Sync time to Gadgetbridge device when connecting, and when time or time zone changes on Android device</string>
|
||||
<string name="pref_title_datetime_syctimeonconnect">Sync time</string>
|
||||
<string name="pref_header_datetime">Date and Time</string>
|
||||
<string name="pref_default">Default</string>
|
||||
<string name="pref_title_general_autostartonboot">Start automatically</string>
|
||||
<string name="pref_title_general_autoconnectonbluetooth">Connect to Gadgetbridge device when Bluetooth is turned on</string>
|
||||
<string name="pref_header_general">General settings</string>
|
||||
<string name="title_activity_settings">Settings</string>
|
||||
<string name="miband_firmware_suggest_whitelist">If you still want to proceed and things continue to work properly afterwards, please tell the Gadgetbridge developers to whitelist the %s firmware version.</string>
|
||||
<string name="miband_firmware_unknown_warning">This firmware is untested and may not be compatible with Gadgetbridge.
|
||||
\n
|
||||
\nYou are DISCOURAGED from flashing it!</string>
|
||||
<string name="miband_firmware_known">This firmware has been tested and is known to be compatible with Gadgetbridge.</string>
|
||||
<string name="dbmanagementactivity_import_data_title">Import Data\?</string>
|
||||
<string name="dbmanagementactivity_error_exporting_shared">Error exporting preference: %1$s</string>
|
||||
<string name="dbmanagementactivity_error_exporting_db">Error exporting DB: %1$s</string>
|
||||
<string name="dbmanagementactivity_exported_to">Exported to: %1$s</string>
|
||||
<string name="dbmanagementactivvity_cannot_access_export_path">Cannot access export path. Please contact the developers.</string>
|
||||
<string name="activity_db_management_merge_old_title">Legacy database delete</string>
|
||||
<string name="activity_db_management_import_export_explanation">The database operations use the following path on your device.
|
||||
\nThis path is accessible to other Android apps and your computer.
|
||||
\nExpect to find your exported database (or place the database you want to import) there:</string>
|
||||
<string name="title_activity_db_management">Database management</string>
|
||||
<string name="action_db_management">Database management</string>
|
||||
<string name="fw_multi_upgrade_notice">You are about to install the %1$s and %2$s firmware, instead of the ones currently on your Mi Band.</string>
|
||||
<string name="fw_upgrade_notice">You are about to install the %s.</string>
|
||||
<string name="title_activity_fw_app_insaller">FW/App installer</string>
|
||||
<string name="title_activity_calblacklist">Blacklisted Calendars</string>
|
||||
<string name="title_activity_appblacklist">Notification blacklist</string>
|
||||
<string name="app_move_to_top">Move to top</string>
|
||||
<string name="app_configure">Configure</string>
|
||||
<string name="appmanager_weather_install_provider">Install the Weather Notification app</string>
|
||||
<string name="appmanager_weather_deactivate">Deactivate System Weather app</string>
|
||||
<string name="appmanager_weather_activate">Activate System Weather app</string>
|
||||
<string name="appmanager_hrm_deactivate">Deactivate HRM</string>
|
||||
<string name="appmanager_hrm_activate">Activate HRM</string>
|
||||
<string name="appmanager_health_deactivate">Deactivate</string>
|
||||
<string name="appmanager_health_activate">Activate</string>
|
||||
<string name="appmanager_app_openinstore">Search in Pebble appstore</string>
|
||||
<string name="appmananger_app_reinstall">Reinstall</string>
|
||||
<string name="appmananger_app_delete_cache">Delete and remove from cache</string>
|
||||
<string name="appmananger_app_delete">Delete</string>
|
||||
<string name="appmanager_installed_watchfaces">Installed watchfaces</string>
|
||||
<string name="appmanager_installed_watchapps">Installed apps</string>
|
||||
<string name="appmanager_cached_watchapps_watchfaces">Apps in cache</string>
|
||||
<string name="title_activity_appmanager">App Manager</string>
|
||||
<string name="title_activity_debug">Debug</string>
|
||||
<string name="controlcenter_snackbar_requested_screenshot">Taking a screenshot of the device</string>
|
||||
<string name="controlcenter_snackbar_connecting">Connecting…</string>
|
||||
<string name="controlcenter_snackbar_disconnecting">Disconnecting</string>
|
||||
<string name="controlcenter_snackbar_need_longpress">Long press the card to disconnect</string>
|
||||
<string name="controlcenter_navigation_drawer_close">Close navigation drawer</string>
|
||||
<string name="controlcenter_navigation_drawer_open">Open navigation drawer</string>
|
||||
<string name="controlcenter_delete_device_dialogmessage">This will delete the device and all associated data!</string>
|
||||
<string name="controlcenter_delete_device_name">Delete %1$s</string>
|
||||
<string name="controlcenter_delete_device">Delete Device</string>
|
||||
<string name="controlcenter_disconnect">Disconnect</string>
|
||||
<string name="controlcenter_take_screenshot">Take Screenshot</string>
|
||||
<string name="controlcenter_find_device">Find lost device</string>
|
||||
<string name="controlcenter_fetch_activity_data">Synchronize</string>
|
||||
<string name="action_donate">Donate</string>
|
||||
<string name="action_quit">Quit</string>
|
||||
<string name="action_debug">Debug</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="title_activity_controlcenter">Gadgetbridge</string>
|
||||
<string name="app_name">Gadgetbridge</string>
|
||||
</resources>
|
@ -829,4 +829,19 @@
|
||||
<string name="devicetype_banglejs">Bangle.js</string>
|
||||
<string name="devicetype_y5">Y5</string>
|
||||
<string name="devicetype_itag">iTag</string>
|
||||
<string name="pref_title_lower_button_function">Botón inferior</string>
|
||||
<string name="pref_title_middle_button_function">Botón central</string>
|
||||
<string name="pref_title_upper_button_function">Botón superior</string>
|
||||
<string name="hr_appname_commute">Conmutar</string>
|
||||
<string name="hr_appname_stopwatch">Cronógrafa</string>
|
||||
<string name="hr_appname_workout">Rutina de ejercicio</string>
|
||||
<string name="hr_appname_wellness">Bienestar</string>
|
||||
<string name="pref_summary_force_white_color_scheme">Útil si tu reloj tiene manecillas oscuras</string>
|
||||
<string name="find_my_phone_notification">Encuentra mi teléfono</string>
|
||||
<string name="pref_title_vibration_strength">Resistencia a la vibración</string>
|
||||
<string name="pref_title_relax_firmware_checks">Habilite esto si desea actualizar un firmware no destinado a su dispositivo (bajo su propio riesgo)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Relaje las comprobaciones de firmware</string>
|
||||
<string name="pref_title_allow_high_mtu">Permitir MTU alta</string>
|
||||
<string name="pref_summary_custom_deviceicon">Mostrar un icono de notificación de Android específico del dispositivo en lugar del icono de Gadgetbridge cuando esté conectado</string>
|
||||
<string name="pref_title_custom_deviceicon">Mostrar icono de notificación específica del dispositivo</string>
|
||||
</resources>
|
853
app/src/main/res/values-fr-rCA/strings.xml
Normal file
853
app/src/main/res/values-fr-rCA/strings.xml
Normal file
@ -0,0 +1,853 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="discovery_pair_title">Appairer avec %1$s\?</string>
|
||||
<string name="dbmanagementactivity_delete_old_activitydb_confirmation">Voulez-vous vraiment détruire entièrement la base de données\? Toutes vos données non importées seront perdues.</string>
|
||||
<string name="dbmanagementactivity_delete_old_activity_db">Voulez-vous détruire les anciennes activités de la base de données\?</string>
|
||||
<string name="dbmanagementactivity_really_delete_entire_db">Voulez-vous vraiment détruire entièrement la base de données\? Toutes vos données d\'activité et vos informations issues de vos appareils seront perdues.</string>
|
||||
<string name="dbmanagementactivity_delete_activity_data_title">Détruire les anciennes données\?</string>
|
||||
<string name="dbmanagementactivity_overwrite_database_confirmation">Voulez-vous vraiment effacer la base de données actuelle\? Toutes vos données (si vous en avez) seront perdues.</string>
|
||||
<string name="dbmanagementactivity_import_data_title">Importer des données\?</string>
|
||||
<string name="chart_no_data_synchronize">Aucune donnée. Synchroniser l\'appareil\?</string>
|
||||
<string name="prefs_wearside">Port main gauche ou droite\?</string>
|
||||
<string name="cannot_connect_bt_address_invalid_">Connexion impossible. L’adresse Bluetooth est-elle valide\?</string>
|
||||
<string name="debugactivity_really_factoryreset_title">Vraiment retourner aux paramètres d\'usine\?</string>
|
||||
<string name="mi2_fw_installhandler_fw53_hint">Vous devez installer la version %1$s avant d\'installer ce micrologiciel!</string>
|
||||
<string name="find_lost_device_you_found_it">Trouvé!</string>
|
||||
<string name="find_device_you_found_it">Vous l\'avez trouvé!</string>
|
||||
<string name="updatefirmwareoperation_updateproblem_do_not_reboot">Problème avec le transfert du micrologiciel. Ne redémarrez pas votre Mi Band!</string>
|
||||
<string name="pbwinstallhandler_incorrect_hw_revision">Version du matériel incorrecte!</string>
|
||||
<string name="miband_fwinstaller_untested_version">Version non testée!</string>
|
||||
<string name="notif_export_failed_title">L\'exportation de la base de données a échoué! Veuillez vérifier vos paramètres.</string>
|
||||
<string name="pref_auto_fetch_summary">Récupération au déverrouillage de l\'écran. Fonctionne uniquement si un mécanisme de verrouillage est configuré!</string>
|
||||
<string name="pref_summary_pebble_forceuntested">Activer les fonctionnalités non-testées. À VOS PROPRES RISQUES ET PÉRILS!</string>
|
||||
<string name="miband_firmware_unknown_warning">Ce micrologiciel n\'a pas été testé et peut ne pas être compatible avec Gadgetbridge.
|
||||
\n
|
||||
\nIl n\'est PAS conseillé de le flasher!</string>
|
||||
<string name="fw_upgrade_notice_miband4">Vous êtes sur le point d\'installer le firmware %s sur votre Mi Band 4.
|
||||
\n
|
||||
\nVeuillez vous assurez d\'installer le fichier .fw, et après que le fichier .res. Votre bracelet redémarrera après l\'installation du fichier .fw.
|
||||
\n
|
||||
\nRemarque : Vous n\'avez pas à installer .res s\'il est exactement le même que celui précédemment installé.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS ET PÉRILS!</string>
|
||||
<string name="fw_upgrade_notice_miband3">Vous allez installer le micrologiciel %s dans votre Mi Band 3.
|
||||
\n
|
||||
\nAssurez-vous d\'installer d\'abord le fichier .fw, et ensuite le fichiers .res. Votre bracelet redémarrera après l\'installation du fichiers .fw.
|
||||
\n
|
||||
\nRemarque : Vous n\'avez pas besoin d\'installer le fichier .res si c\'est exactement le même que celui déjà installé.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS ET PÉRILS!</string>
|
||||
<string name="fw_upgrade_notice_amazfitgts">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit GTS.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res et enfin le fichier .gps. Votre montre redémarrera après installation du fichier .fw.
|
||||
\n
|
||||
\nNote : vous n\'avez pas à installer les fichiers .res et .gps s\'ils sont exactement les mêmes que ceux installés précédemment.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS ET PÉRILS!</string>
|
||||
<string name="fw_upgrade_notice_amazfitgtr">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit GTR.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res et enfin le fichier .gps. Votre montre redémarrera après installation du fichier .fw.
|
||||
\n
|
||||
\nNote : vous n\'avez pas à installer les fichiers .res et .gps s\'ils sont exactement les mêmes que ceux installés précédemment.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS ET PÉRILS!</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor2">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Cor 2.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res. Votre montre redémarrera après installation du .fw.
|
||||
\n
|
||||
\nNote : il n\'est pas nécessaire d\'installer le fichier .res si celui-ci est identique à celui installé précédemment.
|
||||
\n
|
||||
\nCONTINUEZ À VOS RISQUES ET PÉRILS!
|
||||
\n
|
||||
\nNON TESTÉ, IL PEUT ÊTRE NÉCESSAIRE DE FLASHER UN MICROLOGICIEL BEATS_W SI LE NOM DE L\'APPAREIL EST « Amazfit Band 2 »</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Cor.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res. Votre montre redémarrera après installation du .fw.
|
||||
\n
|
||||
\nNote : vous ne devez pas installer .res si celui-ci est identique à celui installé précédemment.
|
||||
\n
|
||||
\nCONTINUEZ À VOS RISQUES ET PÉRILS!</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip_lite">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Bip Lite.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res. Votre montre redémarrera après installation du fichier .fw.
|
||||
\n
|
||||
\nNote : vous n\'avez pas à installer le fichier .res si c\'est exactement le même que celui installé précédemment.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS!</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Bip.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res, puis le fichier.gps.. Votre montre redémarrera après installation du .fw.
|
||||
\n
|
||||
\nNote : vous ne devez pas installer les fichiers .res et .gps si ceux-ci sont identiques à ceux installés précédemment.
|
||||
\n
|
||||
\nCONTINUEZ À VOS RISQUES ET PÉRILS!</string>
|
||||
<string name="controlcenter_delete_device_dialogmessage">Ceci va supprimer l’appareil et toutes les données associées!</string>
|
||||
<string name="watch9_time_hours">Heures :</string>
|
||||
<string name="watch9_time_minutes">Minutes :</string>
|
||||
<string name="activity_db_management_empty_db_warning">Attention! En cliquant sur ce bouton, vous supprimerez toutes vos données et recommencerez à zéro.</string>
|
||||
<string name="live_activity_max_heart_rate">Mesure cardiaque actuelle / maximum : %1$d / %2$d</string>
|
||||
<string name="overstep">Trop d\'activité : %1$d</string>
|
||||
<string name="lack_of_step">Manque d\'activité : %1$d</string>
|
||||
<string name="overslept">Excès de sommeil : %1$s</string>
|
||||
<string name="lack_of_sleep">Manque de sommeil : %1$s</string>
|
||||
<string name="zetime_activity_tracking_summary">Activer le suivi des activités : comptera vos pas, etc.</string>
|
||||
<string name="pref_summary_pebble_forceprotocol">Cette option force l\'utilisation du protocole de notification le plus récent selon votre version du micrologiciel. À VOS RISQUES ET PÉRILS!</string>
|
||||
<string name="pref_summary_location_keep_uptodate">Essayer de garder la localisation à jour pendant le fonctionnement, sinon utiliser l’emplacement enregistré</string>
|
||||
<string name="hr_widget_calories">Calories</string>
|
||||
<string name="appwidget_text">Zzz</string>
|
||||
<string name="menuitem_alipay">Alipay</string>
|
||||
<string name="devicetype_amazfit_gts">Amazfit GTS</string>
|
||||
<string name="devicetype_makibes_hr3">Makibes HR3</string>
|
||||
<string name="devicetype_mijia_lywsd02">Mijia Smart Clock</string>
|
||||
<string name="devicetype_itag">iTag</string>
|
||||
<string name="devicetype_miscale2">Mi Scale 2</string>
|
||||
<string name="devicetype_casiogb6900">Casio GB-6900</string>
|
||||
<string name="devicetype_roidmi3">Roidmi 3</string>
|
||||
<string name="devicetype_roidmi">Roidmi</string>
|
||||
<string name="devicetype_watch9">Watch 9</string>
|
||||
<string name="devicetype_mykronoz_zetime">MyKronoz ZeTime</string>
|
||||
<string name="devicetype_qhybrid">Fossil Q Hybrid</string>
|
||||
<string name="devicetype_xwatch">XWatch</string>
|
||||
<string name="devicetype_teclast_h30">Teclast H30</string>
|
||||
<string name="devicetype_exrizu_k8">Exrizu K8</string>
|
||||
<string name="devicetype_makibes_f68">Makibes F68</string>
|
||||
<string name="devicetype_hplus">HPlus</string>
|
||||
<string name="devicetype_liveview">LiveView</string>
|
||||
<string name="devicetype_vibratissimo">Vibratissimo</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="devicetype_amazfit_gtr">Amazfit GTR</string>
|
||||
<string name="devicetype_amazfit_cor2">Amazfit Cor 2</string>
|
||||
<string name="devicetype_amazfit_cor">Amazfit Cor</string>
|
||||
<string name="devicetype_amazfit_bip_lite">Amazfit Bip Lite</string>
|
||||
<string name="devicetype_amazfit_bip">Amazfit Bip</string>
|
||||
<string name="devicetype_miband4">Mi Band 4</string>
|
||||
<string name="devicetype_miband3">Mi Band 3</string>
|
||||
<string name="devicetype_miband2">Mi Band 2</string>
|
||||
<string name="devicetype_miband">Mi Band</string>
|
||||
<string name="devicetype_pebble">Pebble</string>
|
||||
<string name="title_activity_vibration">Vibration</string>
|
||||
<string name="calories">Calories</string>
|
||||
<string name="miband_prefs_vibration">Vibration</string>
|
||||
<string name="vibration_profile_long">Long</string>
|
||||
<string name="title_activity_controlcenter">Gadgetbridge</string>
|
||||
<string name="app_name">Gadgetbridge</string>
|
||||
<plurals name="widget_alarm_target_hours">
|
||||
<item quantity="one">%d heure</item>
|
||||
<item quantity="other">%d heures</item>
|
||||
</plurals>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Tracer les cercles Widget</string>
|
||||
<string name="pbwinstallhandler_app_item">%1$s (%2$s)</string>
|
||||
<string name="installhandler_firmware_name">%1$s: %2$s %3$s</string>
|
||||
<string name="notif_battery_low_extended">%1$s pile faible : %2$s</string>
|
||||
<string name="notif_battery_low">%1$s pile faible</string>
|
||||
<string name="notif_battery_low_percent">%1$s pile restante : %2$s%%</string>
|
||||
<string name="device_with_rssi">%1$s (%2$s)</string>
|
||||
<string name="appversion_by_creator">%1$s par %2$s</string>
|
||||
<string name="pref_header_auto_fetch">Récupération automatique</string>
|
||||
<string name="pref_title_relax_firmware_checks">Activez cette option si vous souhaitez flasher un microprogramme qui n\'est pas destiné à votre appareil (à vos propres risques)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Assouplir les contrôles des microprogrammes</string>
|
||||
<string name="pref_title_vibration_strength">Puissance du vibreur</string>
|
||||
<string name="pref_title_lower_button_function">Bouton inférieur</string>
|
||||
<string name="pref_title_middle_button_function">Bouton du milieu</string>
|
||||
<string name="pref_title_upper_button_function">Bouton supérieur</string>
|
||||
<string name="hr_appname_commute">Trajet</string>
|
||||
<string name="hr_appname_stopwatch">Chronomètre</string>
|
||||
<string name="hr_appname_workout">Entraînement</string>
|
||||
<string name="hr_appname_wellness">Bien-être</string>
|
||||
<string name="pref_summary_custom_deviceicon">Afficher une icône de notification Android spécifique à l\'appareil à la place de l\'icône Gadgetbridge lors de la connexion</string>
|
||||
<string name="pref_title_custom_deviceicon">Afficher l’icône de notification spécifique à l’appareil</string>
|
||||
<string name="notification_channel_high_priority_name">Priorité haute des notifications Gadgetbridge</string>
|
||||
<string name="find_my_phone_notification">Trouver mon téléphone</string>
|
||||
<string name="pref_summary_force_white_color_scheme">Utile si votre montre a les mains noires</string>
|
||||
<string name="pref_title_force_white_color_scheme">Forcer le noir sur le blanc</string>
|
||||
<string name="hr_widget_nothing">Rien</string>
|
||||
<string name="hr_widget_weather">Météo</string>
|
||||
<string name="hr_widget_active_minutes">Les minutes actives</string>
|
||||
<string name="hr_widget_date">Date</string>
|
||||
<string name="hr_widget_steps">Étapes</string>
|
||||
<string name="hr_widget_heart_rate">Fréquence cardiaque</string>
|
||||
<string name="pref_title_sync_caldendar">Sync calendrier des événements</string>
|
||||
<string name="pref_summary_sync_calendar">Permet les alertes de calendrier, même en cas de déconnexion</string>
|
||||
<string name="pref_summary_allow_high_mtu">Augmente la vitesse de transfert, mais peut ne pas fonctionner avec quelques appareils Android.</string>
|
||||
<string name="pref_title_allow_high_mtu">Autoriser une grande MTU</string>
|
||||
<string name="error_no_location_access">L\'accès à la localisation doit être autorisé et activé pour permettre à la détection de fonctionner correctement</string>
|
||||
<string name="alarm_snooze">Reporter</string>
|
||||
<string name="prefs_button_long_press_action_selection_title">Action d\'appui long de bouton</string>
|
||||
<string name="prefs_button_variable_actions">Paramètres détaillés des appuis de bouton</string>
|
||||
<string name="prefs_button_triple_press_action_selection_title">Action de l\'évènement 3</string>
|
||||
<string name="prefs_button_double_press_action_selection_title">Action de l\'évènement 2</string>
|
||||
<string name="prefs_button_single_press_action_selection_title">Action de l\'évènement 1</string>
|
||||
<string name="devicetype_y5">Y5</string>
|
||||
<string name="devicetype_banglejs">Bangle.js</string>
|
||||
<string name="pref_summary_disable_new_ble_scanning">Cochez cette option si votre appareil ne peut être découvert</string>
|
||||
<string name="pref_disable_new_ble_scanning">Désactiver la nouvelle détection BLE</string>
|
||||
<string name="qhybrid_offset_time_by">décale l\'heure de</string>
|
||||
<string name="qhybrid_changes_delay_prompt">le changement peut prendre quelques secondes…</string>
|
||||
<string name="qhybrid_offset_timezone">décale le fuseau horaire de</string>
|
||||
<string name="qhybrid_buttons_overwrite_error">Une erreur est survenue lors de la modification des boutons</string>
|
||||
<string name="qhybrid_buttons_overwrite_success">Boutons modifiés</string>
|
||||
<string name="qhybrid_prompt_million_steps">Veuillez régler le compteur de pas à un million pour l\'activer.</string>
|
||||
<string name="qhybrid_use_activity_hand_as_notification_counter">utilise l\'activité de la main comme compteur de notification</string>
|
||||
<string name="qhybrid_overwrite_buttons">modifier les boutons</string>
|
||||
<string name="qhybrid_second_timezone_offset_relative_to_utc">décalage du deuxième fuseau horaire par rapport à UTC</string>
|
||||
<string name="qhybrid_time_shift">décalage horaire</string>
|
||||
<string name="qhybrid_goal_in_steps">Objectif de pas</string>
|
||||
<string name="qhybrid_vibration_strength">Puissance de vibration :</string>
|
||||
<string name="watch_not_connected">Montre non connectée</string>
|
||||
<string name="preferences_qhybrid_settings">Paramètres hybrides Q</string>
|
||||
<string name="pref_chart_sleep_rolling_24_off">De midi à midi</string>
|
||||
<string name="pref_chart_sleep_rolling_24_on">Dernières 24 heures</string>
|
||||
<string name="pref_title_chart_sleep_rolling_24_hour">Plage de sommeil</string>
|
||||
<string name="pref_title_chart_heartrate_color">Couleur du rythme cardiaque</string>
|
||||
<string name="pref_chart_heartrate_color_orange">Orange</string>
|
||||
<string name="pref_chart_heartrate_color_red">Rouge</string>
|
||||
<string name="discovery_need_to_enter_authkey">Cet appareil a besoin d\'une clé d\'auth. Pression longue sur celui-ci pour la saisir. Lisez le wiki.</string>
|
||||
<string name="maximum_duration">Durée</string>
|
||||
<string name="prefs_find_phone_duration">Durée de la sonnerie en secondes</string>
|
||||
<string name="prefs_find_phone_summary">Utilisez votre bande pour lire l\'alarme de votre téléphone.</string>
|
||||
<string name="prefs_enable_find_phone">Activer « Trouver le tél. »</string>
|
||||
<string name="prefs_find_phone">Trouver le téléphone</string>
|
||||
<string name="preferences_makibes_hr3_settings">Réglages Makibes HR3</string>
|
||||
<string name="activity_error_no_app_for_gpx">Pour visualiser votre géolocalisation, installez une appli qui lit les fichiers GPX.</string>
|
||||
<string name="pref_display_add_device_fab_off">Visible uniquement si aucun appareil n\'est ajouté</string>
|
||||
<string name="pref_display_add_device_fab_on">Toujours visible</string>
|
||||
<string name="pref_display_add_device_fab">Bouton pour connecter un nouvel appareil</string>
|
||||
<string name="widget_1_hour">1 heure</string>
|
||||
<string name="widget_20_minutes">20 minutes</string>
|
||||
<string name="widget_10_minutes">10 minutes</string>
|
||||
<string name="widget_5_minutes">5 minutes</string>
|
||||
<string name="widget_set_alarm_after">Définir l\'alarme après :</string>
|
||||
<string name="widget_listing_label">État et alarmes</string>
|
||||
<string name="widget_sleep_label">Sommeil : %1$s</string>
|
||||
<string name="widget_steps_label">Pas : %1$02d</string>
|
||||
<string name="appwidget_sleep_alarm_widget_label">Réveil</string>
|
||||
<string name="activity_db_management_exportimport_label">Exporter et Importer</string>
|
||||
<string name="activity_db_management_empty_DB">Vider la base de données</string>
|
||||
<string name="activity_DB_empty_button">Vider la base de données</string>
|
||||
<string name="activity_DB_delete_legacy_button">Supprimer l\'ancienne base de données</string>
|
||||
<string name="activity_DB_test_export_message">Exportation de la base de données…</string>
|
||||
<string name="activity_DB_test_export_button">Lancer immédiatement l\'exportation automatique</string>
|
||||
<string name="activity_DB_import_button">Importer la base de données</string>
|
||||
<string name="activity_DB_ExportButton">Exporter la base de données</string>
|
||||
<string name="activity_db_management_autoexport_label">Exportation automatique</string>
|
||||
<string name="activity_db_management_autoexport_explanation">L\'export automatique des données est réglé vers :</string>
|
||||
<string name="pref_summary_use_custom_font">Activer ceci afin d’afficher les émojis si votre appareil a un micrologiciel de police personnalisée</string>
|
||||
<string name="pref_title_use_custom_font">Utiliser une police personnalisée</string>
|
||||
<string name="pref_title_expose_hr">Accès tiers fréq. cardiaque</string>
|
||||
<string name="pref_summary_expose_hr">Permettre aux autres applis d\'accéder aux données de fréquence cardiaque en temps réel lorsque Gadgetbridge est connecté</string>
|
||||
<string name="menuitem_nfc">NFC</string>
|
||||
<string name="weeksleepchart_sleep_a_month">Sommeil par mois</string>
|
||||
<string name="weekstepschart_steps_a_month">Pas par mois</string>
|
||||
<string name="pref_charts_range_off">Gamme des graphiques positionnée sur une semaine</string>
|
||||
<string name="pref_charts_range_on">Gamme des graphiques positionnée sur un mois</string>
|
||||
<string name="pref_title_charts_range">Gamme des graphiques</string>
|
||||
<string name="pref_title_charts_average">Afficher les moyennes dans les graphiques</string>
|
||||
<string name="pref_header_charts">Paramètres graphiques</string>
|
||||
<string name="average">Moyenne : %1$s</string>
|
||||
<string name="prefs_hr_alarm_high">Limite haute</string>
|
||||
<string name="prefs_hr_alarm_low">Limite basse</string>
|
||||
<string name="prefs_hr_alarm_activity">Alarme de la fréquence cardiaque durant une activité sportive</string>
|
||||
<string name="portuguese">Portugais</string>
|
||||
<string name="vietnamese">Vietnamien</string>
|
||||
<string name="thai">Thaïlandais</string>
|
||||
<string name="indonesian">Indonésien</string>
|
||||
<string name="arabic">Arabe</string>
|
||||
<string name="ukrainian">Ukrainien</string>
|
||||
<string name="turkish">Turc</string>
|
||||
<string name="dutch">Néerlandais</string>
|
||||
<string name="devicetype_bfh16">BFH-16</string>
|
||||
<string name="pref_summary_authkey">Changez la clé auteur à une clé générale sur tous vos appareils Android sur lesquels vous souhaitez vous connecter. La précédente clé par défaut était 0123456789@ABCDE</string>
|
||||
<string name="mi3_prefs_night_mode">Mode nuit</string>
|
||||
<string name="minutes_30">30 minutes</string>
|
||||
<string name="minutes_10">10 minutes</string>
|
||||
<string name="minutes_5">5 minutes</string>
|
||||
<string name="minutes_1">1 minute</string>
|
||||
<string name="seconds_30">30 secondes</string>
|
||||
<string name="seconds_20">20 secondes</string>
|
||||
<string name="seconds_10">10 secondes</string>
|
||||
<string name="seconds_5">5 secondes</string>
|
||||
<string name="no_limit">Sans limite</string>
|
||||
<string name="pref_title_notifications_timeout">Durée minimum entre deux notifications</string>
|
||||
<string name="norwegian_bokmal">Bokmål norvégien</string>
|
||||
<string name="you_did_not_sleep">Vous n\'avez pas dormi</string>
|
||||
<string name="you_slept">Vous avez dormi de %1$s à %2$s</string>
|
||||
<string name="japanese">Japonais</string>
|
||||
<string name="korean">Koréen</string>
|
||||
<string name="polish">Polonais</string>
|
||||
<string name="french">Français</string>
|
||||
<string name="italian">Italien</string>
|
||||
<string name="german">Allemand</string>
|
||||
<string name="mi3_prefs_band_screen_unlock_summary">Glisser le doigt vers le haut pour débloquer l\'écran du bracelet</string>
|
||||
<string name="mi3_prefs_band_screen_unlock">Déverrouillage de l\'écran du Band</string>
|
||||
<string name="title_activity_watch9_calibration">Calibration de la Watch 9</string>
|
||||
<string name="title_activity_watch9_pairing">Appairage de la Watch 9</string>
|
||||
<string name="watch9_calibration_button">Calibrer</string>
|
||||
<string name="watch9_calibration_hint">Régler l\'heure que votre appareil indique actuellement.</string>
|
||||
<string name="watch9_pairing_tap_hint">Lorsque votre bracelet vibre, secouez-le ou pressez son bouton.</string>
|
||||
<string name="controlcenter_calibrate_device">Calibrer l\'appareil</string>
|
||||
<string name="menuitem_music">Musique</string>
|
||||
<string name="menuitem_more">Suite</string>
|
||||
<string name="menuitem_notifications">Notifications</string>
|
||||
<string name="devicetype_id115">ID115</string>
|
||||
<string name="vertical">Vertical</string>
|
||||
<string name="horizontal">Horizontal</string>
|
||||
<string name="prefs_screen_orientation">Orientation de l\'écran</string>
|
||||
<string name="russian">Russe</string>
|
||||
<string name="pref_auto_fetch_limit_fetches_summary">Synchronisation toutes les %d minutes</string>
|
||||
<string name="pref_auto_fetch_limit_fetches">Temps minimum entre synchronisations</string>
|
||||
<string name="pref_auto_fetch">Récupérer automatiquement les données d\'activité</string>
|
||||
<string name="whitelist_all_for_notifications">Mettre toutes les notifications en liste blanche</string>
|
||||
<string name="blacklist_all_for_notifications">Mettre toutes les notifications en liste noire</string>
|
||||
<string name="devicetype_q8">Q8</string>
|
||||
<string name="menuitem_shortcut_weather">Météo (Raccourci)</string>
|
||||
<string name="menuitem_shortcut_alipay">Alipay (Raccourci)</string>
|
||||
<string name="pref_summary_pebble_gatt_clientonly">C\'est uniquement pour les Pebble 2 et expérimental, à essayer si vous avez des problèmes de connectivité</string>
|
||||
<string name="pref_title_pebble_gatt_clientonly">client GATT uniquement</string>
|
||||
<string name="menuitem_settings">Réglages</string>
|
||||
<string name="menuitem_compass">Boussole</string>
|
||||
<string name="menuitem_timer">Minuteur</string>
|
||||
<string name="menuitem_alarm">Alarme</string>
|
||||
<string name="menuitem_weather">Météo</string>
|
||||
<string name="menuitem_activity">Activité</string>
|
||||
<string name="menuitem_status">Etat</string>
|
||||
<string name="reset_index">Réinitialiser la date de récupération</string>
|
||||
<string name="share">Partager</string>
|
||||
<string name="select_all">Tout sélectionner</string>
|
||||
<string name="pref_title_audio_player">Lecteur audio préféré</string>
|
||||
<string name="pref_title_general_autoreconnect">Reconnexion automatique</string>
|
||||
<string name="activity_type_treadmill">Tapis de course</string>
|
||||
<string name="activity_type_biking">Vélo</string>
|
||||
<string name="activity_summaries">Activités</string>
|
||||
<string name="activity_type_unknown">Activité inconnue</string>
|
||||
<string name="activity_type_swimming">Natation</string>
|
||||
<string name="hr_widget_battery">Pile</string>
|
||||
<string name="battery">Pile</string>
|
||||
<string name="notif_battery_low_title">Niveau de la pile faible!</string>
|
||||
<string name="pref_summary_pebble_enable_bgjs">Si activé, autorise l\'affichage de la météo, niveau de la pile, etc.</string>
|
||||
<string name="warning">Attention!</string>
|
||||
<string name="watch9_time_seconds">Secondes :</string>
|
||||
<string name="activity_type_walking">Marche</string>
|
||||
<string name="activity_type_running">Course</string>
|
||||
<string name="activity_type_not_worn">Dispositif non utilisé</string>
|
||||
<string name="activity_type_deep_sleep">Sommeil profond</string>
|
||||
<string name="activity_type_light_sleep">Sommeil léger</string>
|
||||
<string name="activity_type_activity">Activité</string>
|
||||
<string name="activity_type_not_measured">Non mesurée</string>
|
||||
<string name="controlcenter_start_activity_tracks">Suivi de vos activités</string>
|
||||
<string name="on">Actif</string>
|
||||
<string name="notification_channel_name">Notifications de Gadgetbridge</string>
|
||||
<string name="spanish">Espagnol</string>
|
||||
<string name="choose_auto_export_location">Choisissez l\'emplacement d\'exportation</string>
|
||||
<string name="pref_summary_auto_export_interval">Exporter toutes les %d heures</string>
|
||||
<string name="pref_title_auto_export_interval">Intervalle d\'exportation</string>
|
||||
<string name="pref_title_auto_export_location">Emplacement de l\'exportation</string>
|
||||
<string name="pref_title_auto_export_enabled">Exportation automatique activée</string>
|
||||
<string name="pref_header_auto_export">Exporter automatiquement</string>
|
||||
<string name="pref_title_weather">Météo</string>
|
||||
<string name="devicetype_no1_f1">No.1 F1</string>
|
||||
<string name="devicetype_test">Appareil de test</string>
|
||||
<string name="devicetype_unknown">Appareil inconnu</string>
|
||||
<string name="kind_watchface">Cadran</string>
|
||||
<string name="kind_resources">Ressources</string>
|
||||
<string name="kind_gps_cep">Correction d\'erreurs GPS</string>
|
||||
<string name="kind_gps_almanac">Almanach GPS</string>
|
||||
<string name="kind_gps">Micrologiciel GPS</string>
|
||||
<string name="kind_font">Police</string>
|
||||
<string name="kind_invalid">Données non valides</string>
|
||||
<string name="kind_firmware">Micrologiciel</string>
|
||||
<string name="pref_title_weather_location">Emplacement météo (CM/LOS)</string>
|
||||
<string name="interval_one_hour">Une fois par heure</string>
|
||||
<string name="interval_thirty_minutes">Toutes les 30 minutes</string>
|
||||
<string name="interval_ten_minutes">Toutes les 10 minutes</string>
|
||||
<string name="interval_five_minutes">Toutes les 5 minutes</string>
|
||||
<string name="interval_one_minute">Une fois par minute</string>
|
||||
<string name="prefs_title_heartrate_measurement_interval">Mesure du pouls toute la journée</string>
|
||||
<string name="english">Anglais</string>
|
||||
<string name="traditional_chinese">Chinois traditionnel</string>
|
||||
<string name="simplified_chinese">Chinois simplifié</string>
|
||||
<string name="automatic">Automatique</string>
|
||||
<string name="pref_title_charts_swipe">Permettre le balayage gauche/droite dans les graphiques d\'activité</string>
|
||||
<string name="controlcenter_connect">Connexion…</string>
|
||||
<string name="activity_web_view">Activité Web View</string>
|
||||
<string name="pref_title_pebble_enable_bgjs">Activer tâche de fond JS</string>
|
||||
<string name="_pebble_watch_reply">Répondre</string>
|
||||
<string name="_pebble_watch_mute">Silencieux</string>
|
||||
<string name="_pebble_watch_open_on_phone">Ouvrir sur le smartphone Android</string>
|
||||
<string name="mi2_prefs_button_press_count_max_delay_summary">Délai maximum entre pressions en millisecondes</string>
|
||||
<string name="mi2_prefs_button_press_count_max_delay">Délai maximum entre pressions</string>
|
||||
<string name="mi2_prefs_button_action_vibrate_summary">Activer la vibration après déclenchement de l\'action</string>
|
||||
<string name="mi2_prefs_button_action_vibrate">Activer la vibration du bracelet</string>
|
||||
<string name="mi2_prefs_button_action_summary">Activer action après nombre spécifié de pressions</string>
|
||||
<string name="mi2_prefs_button_action">Activer action du bouton</string>
|
||||
<string name="mi2_prefs_button_press_broadcast_summary">Message de diffusion envoyé avec l\'évènement. Le paramètre « button_id » est automatiquement ajouté à chaque message.</string>
|
||||
<string name="mi2_prefs_button_press_broadcast">Message à envoyer</string>
|
||||
<string name="mi2_prefs_button_press_count_summary">Nombre d\'appuis sur le boutton pour envoyer l’Évènement 1. Appuyer de nouveau autant de fois créera l\'Évènement 2, etc.</string>
|
||||
<string name="mi2_prefs_button_press_count">Nombre de pressions du bouton</string>
|
||||
<string name="mi2_prefs_button_actions_summary">Spécifier les actions par pression du bouton</string>
|
||||
<string name="mi2_prefs_button_actions">Actions du bouton</string>
|
||||
<string name="discovery_dont_pair">Ne pas appairer</string>
|
||||
<string name="discovery_yes_pair">Appairer</string>
|
||||
<string name="discovery_pair_question">Sélectionnez Jumeler pour associer vos dispositifs. Si cela échoue, essayez à nouveau sans jumelage.</string>
|
||||
<string name="discovery_successfully_bonded">Lié à %1$s.</string>
|
||||
<string name="discovery_enable_bluetooth">Activez le Bluetooth pour trouver des dispositifs.</string>
|
||||
<string name="discovery_trying_to_connect_to">Tentative de connexion à : %1$s</string>
|
||||
<string name="discovery_bonding_failed_immediately">Le lien avec %1$s a échoué instantanément.</string>
|
||||
<string name="discovery_attempting_to_pair">Tentative de jumelage avec %1$s</string>
|
||||
<string name="mi2_dnd_scheduled">Programmé (intervalle de temps)</string>
|
||||
<string name="mi2_dnd_automatic">Automatique (détection de sommeil)</string>
|
||||
<string name="mi2_dnd_off">Éteint</string>
|
||||
<string name="off">Éteint</string>
|
||||
<string name="mi2_enable_text_notifications_summary">Requis : micrologiciel version 1.0.1.28 ou plus, fichier Mili_pro.ft* installé.</string>
|
||||
<string name="mi2_enable_text_notifications">Notifications textuelles</string>
|
||||
<string name="miband2_prefs_timeformat">Mi2 : format de l\'heure</string>
|
||||
<string name="StringUtils_sender">(%1$s)</string>
|
||||
<string name="pref_screen_notification_profile_alarm_clock">Réveil</string>
|
||||
<string name="timeformat_am_pm">AM/PM</string>
|
||||
<string name="timeformat_24h">24H</string>
|
||||
<string name="unit_imperial">Impériale</string>
|
||||
<string name="unit_metric">Métrique</string>
|
||||
<string name="pref_summary_setup_bt_pairing">Désactivez ceci si vous avez des problèmes de connexion</string>
|
||||
<string name="pref_title_setup_bt_pairing">Activer le jumelage Bluetooth</string>
|
||||
<string name="weather_notification_label">Assurez vous que ce thème soit activé dans l\'application de notification de la météo pour recevoir les informations sur votre Pebble.
|
||||
\n
|
||||
\nAucune configuration n\'est requise.
|
||||
\n
|
||||
\nVous pouvez activer l\'application météo système de votre Pebble depuis la configuration de l\'application.
|
||||
\n
|
||||
\nLes watchfaces supportées afficheront la météo automatiquement.</string>
|
||||
<string name="pebble_pairing_hint">Une fenêtre de jumelage va s’afficher sur votre téléphone. Si cela ne se produit pas, regardez dans vos notifications et acceptez-la. Acceptez ensuite la demande de jumelage sur votre Pebble.</string>
|
||||
<string name="title_activity_pebble_pairing">Jumelage avec une Pebble</string>
|
||||
<string name="Delete">Supprimer</string>
|
||||
<string name="Cancel">Annuler</string>
|
||||
<string name="dbmanagementactivity_overwrite">Écraser</string>
|
||||
<string name="dbmanagementactivity_old_activity_db_deletion_failed">Échec de la destruction de l\'ancienne base de données.</string>
|
||||
<string name="dbmanagementactivity_old_activity_db_successfully_deleted">Les anciennes données d\'activité ont été effacées.</string>
|
||||
<string name="dbmanagementactivity_db_deletion_failed">Échec de la destruction de la base de données.</string>
|
||||
<string name="dbmanagementactivity_database_successfully_deleted">Les données ont été effacées.</string>
|
||||
<string name="dbmanagementactivity_error_importing_shared">Erreur d\'importation des préférences : %1$s</string>
|
||||
<string name="dbmanagementactivity_error_importing_db">Erreur lors de l\'importation de la base de données : %1$s</string>
|
||||
<string name="dbmanagementactivity_import_successful">Importé.</string>
|
||||
<string name="dbmanagementactivity_error_exporting_shared">Erreur d\'exportation des préférences : %1$s</string>
|
||||
<string name="dbmanagementactivity_error_exporting_db">Erreur d\'exportation de la base de données : %1$s</string>
|
||||
<string name="dbmanagementactivity_exported_to">Exporter vers : %1$s</string>
|
||||
<string name="pref_title_pebble_health_store_raw">Stockez les enregistrements brut dans la base de données</string>
|
||||
<string name="live_activity_heart_rate">Fréquence cardiaque</string>
|
||||
<string name="charts_legend_heartrate">Fréquence cardiaque</string>
|
||||
<string name="updatefirmwareoperation_firmware_not_sent">Échec lors de l\'écriture du micrologiciel</string>
|
||||
<string name="updatefirmwareoperation_update_in_progress">Installation du micrologiciel</string>
|
||||
<string name="DEVINFO_HR_VER">"Fréquence cardiaque : "</string>
|
||||
<string name="error_creating_directory_for_logfiles">Erreur à la création de votre fichier log : %1$s</string>
|
||||
<string name="device_fw">Version du micrologiciel : %1$s</string>
|
||||
<string name="device_hw">Révision matérielle : %1$s</string>
|
||||
<string name="activity_prefs_sleep_duration">Temps de sommeil préféré en heures</string>
|
||||
<string name="add_widget">Ajouter un widget</string>
|
||||
<string name="authentication_required">Authentification requise</string>
|
||||
<string name="authenticating">Authentification</string>
|
||||
<string name="activity_prefs_weight_kg">Poids en kg</string>
|
||||
<string name="activity_prefs_height_cm">Taille en cm</string>
|
||||
<string name="activity_prefs_gender">Sexe</string>
|
||||
<string name="activity_prefs_year_birth">Année de naissance</string>
|
||||
<string name="activity_prefs_about_you">À propos de vous</string>
|
||||
<string name="waiting_for_reconnect">En attente de reconnexion</string>
|
||||
<string name="FetchActivityOperation_about_to_transfer_since">Sur le point de transférer des données depuis %1$s</string>
|
||||
<string name="mi2_prefs_do_not_disturb_end">Heure de fin</string>
|
||||
<string name="mi2_prefs_do_not_disturb_start">Heure de début</string>
|
||||
<string name="mi2_prefs_inactivity_warnings_dnd_summary">Désactiver les alertes d\'inactivité pendant un intervalle de temps</string>
|
||||
<string name="mi2_prefs_inactivity_warnings_threshold">Seuil d\'inactivité (en minutes)</string>
|
||||
<string name="mi2_prefs_inactivity_warnings_summary">Le bracelet vibrera si vous n\'êtes pas actif pendant un moment</string>
|
||||
<string name="mi2_prefs_inactivity_warnings">Alertes d\'inactivité</string>
|
||||
<string name="mi2_prefs_do_not_disturb_summary">Le bracelet ne recevra pas de notifications si activé</string>
|
||||
<string name="mi2_prefs_do_not_disturb">Ne Pas Déranger</string>
|
||||
<string name="mi2_prefs_rotate_wrist_to_switch_info">Tournez votre poignet pour changer d\'élément</string>
|
||||
<string name="mi2_prefs_activate_display_on_lift">Allumer l\'écran lors d\'un mouvement</string>
|
||||
<string name="mi2_prefs_display_items_summary">Choisissez les éléments à afficher sur le bracelet</string>
|
||||
<string name="mi2_prefs_display_items">Éléments à afficher</string>
|
||||
<string name="mi2_prefs_goal_notification_summary">Le bracelet vibrera lorsque l\'objectif de pas quotidien sera atteint</string>
|
||||
<string name="mi2_prefs_goal_notification">Notification d\'objectif</string>
|
||||
<string name="dateformat_date_time">Date et heure</string>
|
||||
<string name="dateformat_time">Heure</string>
|
||||
<string name="miband2_prefs_dateformat">Format de la date</string>
|
||||
<string name="miband_prefs_device_time_offset_hours">La compensation de temps en heure (pour travailleurs en rotation, par exemple)</string>
|
||||
<string name="miband_prefs_hr_sleep_detection">Utiliser le capteur cardiaque pour améliorer la détection du sommeil</string>
|
||||
<string name="miband_prefs_reserve_alarm_calendar">Alarmes à réserver pour événements futurs</string>
|
||||
<string name="fwinstaller_firmware_not_compatible_to_device">Ce micrologiciel n\'est pas compatible avec l\'appareil</string>
|
||||
<string name="miband_fwinstaller_incompatible_version">Micrologiciel non compatible</string>
|
||||
<string name="pref_title_keep_data_on_device">Conserver les activités sur l\'appareil</string>
|
||||
<string name="user_feedback_all_alarms_disabled">Toutes alarmes désactivées</string>
|
||||
<string name="device_not_connected">Non connecté.</string>
|
||||
<string name="abstract_chart_fragment_kind_not_worn">Non porté</string>
|
||||
<string name="abstract_chart_fragment_kind_deep_sleep">Sommeil profond</string>
|
||||
<string name="abstract_chart_fragment_kind_light_sleep">Sommeil léger</string>
|
||||
<string name="abstract_chart_fragment_kind_activity">Activité</string>
|
||||
<string name="live_activity_start_your_activity">Démarrez votre activité</string>
|
||||
<string name="live_activity_steps_per_minute_history">Historique de pas/minute</string>
|
||||
<string name="live_activity_total_steps">Nombre total de pas</string>
|
||||
<string name="live_activity_current_steps_per_minute">Pas/minute actuel</string>
|
||||
<string name="live_activity_steps_history">Historique de pas</string>
|
||||
<string name="pref_summary_low_latency_fw_update">Cela peut aider sur les appareils où les installations de micrologiciel échouent.</string>
|
||||
<string name="pref_title_low_latency_fw_update">Utilisez le mode basse latence pour installer un micrologiciel</string>
|
||||
<string name="pref_summary_keep_data_on_device">Les données d\'activités seront conservées sur le Mi Band après la synchronisation. Utile si GB est utilisé avec d\'autres applications.</string>
|
||||
<string name="pref_summary_dont_ack_transfers">Les données d\'activités ne seront pas effacées du bracelet si elles ne sont pas confirmées. Utile si GB est utilisé avec d\'autres applications.</string>
|
||||
<string name="pref_title_dont_ack_transfer">Ne pas confirmer le transfert de données d\'activités</string>
|
||||
<string name="weeksteps_today_steps_description">Nombre de pas aujourd\'hui, objectif : %1$s</string>
|
||||
<string name="liveactivity_live_activity">Activité en direct</string>
|
||||
<string name="heart_rate">Fréquence cardiaque</string>
|
||||
<string name="clock">Horloge</string>
|
||||
<string name="distance">Distance</string>
|
||||
<string name="chart_steps">Pas</string>
|
||||
<string name="updatefirmwareoperation_write_failed">Échec lors de l\'installation du micrologiciel</string>
|
||||
<string name="updatefirmwareoperation_update_complete_rebooting">Installation complète du micrologiciel, redémarrage de l\'appareil…</string>
|
||||
<string name="updatefirmwareoperation_update_complete">Installation complète du micrologiciel</string>
|
||||
<string name="updatefirmwareoperation_metadata_updateproblem">Problème avec le transfert de métadonnées du micrologiciel</string>
|
||||
<string name="pbwinstallhandler_correct_hw_revision">Version du matériel correcte</string>
|
||||
<string name="pbw_installhandler_pebble_firmware">Micrologiciel Pebble %1$s</string>
|
||||
<string name="fwappinstaller_connection_state">Connexion à l\'appareil : %1$s</string>
|
||||
<string name="pref_title_authkey">Clé Auteur</string>
|
||||
<string name="title_activity_device_specific_settings">Paramètres spécifiques de l\'appareil</string>
|
||||
<string name="pref_title_support_voip_calls">Activer les applications d\'appel VoIP</string>
|
||||
<string name="activity_prefs_activetime_minutes">Objectif quotidien : temps d\'activité en minutes</string>
|
||||
<string name="activity_prefs_distance_meters">Objectif quotidien : distance en mètres</string>
|
||||
<string name="activity_prefs_calories_burnt">Objectif quotidien : calories brulées</string>
|
||||
<string name="interval_forty_five_minutes">Toutes les 45 min</string>
|
||||
<string name="interval_fifteen_minutes">Toutes les 15 min</string>
|
||||
<string name="pref_screen_notification_profile_anti_loss">Alerte Anti-Perte</string>
|
||||
<string name="pref_screen_notification_profile_low_power">Alerte batterie faible</string>
|
||||
<string name="pref_screen_notification_profile_inactivity">Notification d\'inactivité</string>
|
||||
<string name="pref_screen_notification_profile_calendar">Notification du calendrier</string>
|
||||
<string name="pref_screen_notification_profile_missed_call">Notification appel manqué</string>
|
||||
<string name="zetime_signaling_vibrate_beep_once">Vibration et bip uniques</string>
|
||||
<string name="zetime_signaling_beep_twice">Bip double</string>
|
||||
<string name="zetime_signaling_beep_once">Bip unique</string>
|
||||
<string name="zetime_signaling_vibrate_twice">Vibration double</string>
|
||||
<string name="zetime_signaling_vibrate_once">Vibration unique</string>
|
||||
<string name="zetime_signaling_vibrate_beep">Vibration et bip continus</string>
|
||||
<string name="zetime_signaling_beep">Bip continu</string>
|
||||
<string name="zetime_signaling_vibrate">Vibration continue</string>
|
||||
<string name="zetime_signaling_none">Silencieux</string>
|
||||
<string name="zetime_title_alarm_signaling">Type de signal pour l\'alarme</string>
|
||||
<string name="zetime_prefs_inactivity_su">Dimanche</string>
|
||||
<string name="zetime_prefs_inactivity_sa">Samedi</string>
|
||||
<string name="zetime_prefs_inactivity_fr">Vendredi</string>
|
||||
<string name="zetime_prefs_inactivity_th">Jeudi</string>
|
||||
<string name="zetime_prefs_inactivity_we">Mercredi</string>
|
||||
<string name="zetime_prefs_inactivity_tu">Mardi</string>
|
||||
<string name="zetime_prefs_inactivity_mo">Lundi</string>
|
||||
<string name="zetime_prefs_inactivity_repetitions">Répétitions</string>
|
||||
<string name="zetime_date_format_3">mm/jj/aaaa</string>
|
||||
<string name="zetime_date_format_2">jj/mm/aaaa</string>
|
||||
<string name="zetime_date_format_1">aaaa/mm/jj</string>
|
||||
<string name="zetime_date_format">Format de la date</string>
|
||||
<string name="zetime_calories_type_all">Calories brûlées activement et au repos</string>
|
||||
<string name="zetime_calories_type_active">Seulement les calories brûlées activement</string>
|
||||
<string name="zetime_calories_type">Type de calories</string>
|
||||
<string name="zetime_handmove_display_summary">Tourner le poignet pour activer ou désactiver l\'écran.</string>
|
||||
<string name="zetime_handmove_display">Mouvement de la main</string>
|
||||
<string name="zetime_activity_tracking">Suivi des Activités</string>
|
||||
<string name="zetime_analog_mode_handsandsteps">Aiguilles et Pas</string>
|
||||
<string name="zetime_analog_mode_hands">Aiguilles seulement</string>
|
||||
<string name="zetime_analog_mode">Mode analogique</string>
|
||||
<string name="activity_prefs_alarm_min_heart_rate">Fréquence cardiaque minimale</string>
|
||||
<string name="activity_prefs_alarm_max_heart_rate">Fréquence cardiaque maximale</string>
|
||||
<string name="zetime_heart_rate_alarm_enable">Activer l\'alarme de fréquence cardiaque</string>
|
||||
<string name="zetime_title_heart_rate_alarm_summary">La montre vous alertera quand votre fréquence cardiaque dépasse les limites.</string>
|
||||
<string name="zetime_title_heart_rate_alarm">Alarme Fréquence Cardiaque</string>
|
||||
<string name="zetime_title_screentime">Durée d\'écran allumé en secondes</string>
|
||||
<string name="zetime_title_heartrate">Paramètres Fréquence Cardiaque</string>
|
||||
<string name="zetime_title_settings">Paramètres ZeTime</string>
|
||||
<string name="prefs_disconnect_notification">Notification de déconnexion</string>
|
||||
<string name="activity_type_exercise">Activité physique</string>
|
||||
<string name="appwidget_not_connected">Non connecté, l\'alarme n\'est pas définie.</string>
|
||||
<string name="save_configuration">Sauvegarder la configuration</string>
|
||||
<string name="mode_configuration">Mode Configuration</string>
|
||||
<string name="filter_mode">Mode Filtre</string>
|
||||
<string name="toast_notification_filter_words_empty_hint">Veuillez entrer au moins un mot</string>
|
||||
<string name="filter_submode_all">Tous les mots</string>
|
||||
<string name="filter_submode_at_least_one">Au moins un des mots</string>
|
||||
<string name="filter_mode_blacklist">Bloquer lorsque contient les mots</string>
|
||||
<string name="filter_mode_whitelist">Montrer lorsque contient les mots</string>
|
||||
<string name="filter_mode_none">Ne pas filtrer</string>
|
||||
<string name="toast_notification_filter_saved_successfully">Filtre des notifications sauvegardé</string>
|
||||
<string name="edittext_notification_filter_words_hint">Saisissez les mots désirés, chacun sur une ligne</string>
|
||||
<string name="toast_app_must_not_be_blacklisted">L\'application ne doit pas être en liste noire pour pouvoir être configurée</string>
|
||||
<string name="title_activity_notification_filter">Filtre de notifications</string>
|
||||
<string name="appwidget_setting_alarm">Une alarme a été enregistré pour %1$02d:%2$02d</string>
|
||||
<string name="debugactivity_really_factoryreset">Une réinitialisation effacera toutes les données de l\'appareil connecté (si supporté). Les appareils Xiaomi/Huami modifient également l\'adresse MAC Bluetooth, de sorte qu\'ils apparaissent comme de nouveaux appareils dans Gadgetbridge.</string>
|
||||
<string name="no_data">Pas de données</string>
|
||||
<string name="language_and_region_prefs">Paramètres de langue et de région</string>
|
||||
<string name="preferences_rtl_settings">Support Droite-à-Gauche</string>
|
||||
<string name="pref_summary_contextual_arabic">A cocher pour activer le support \"Arabe contextuel\"</string>
|
||||
<string name="pref_title_contextual_arabic">Arabe contextuel</string>
|
||||
<string name="pref_rtl_max_line_length_summary">Allonge ou raccourcis les lignes dans les textes écrits de droite à gauche</string>
|
||||
<string name="pref_rtl_max_line_length">Longueur max. d\'une ligne en mode Droite-à-Gauche</string>
|
||||
<string name="pref_summary_rtl">Cocher ceci si votre appareil n\'est pas compatible avec les langues \"droite-à-gauche\"</string>
|
||||
<string name="pref_title_rtl">De droite à gauche</string>
|
||||
<string name="activity_prefs_chart_min_heart_rate">Fréquence cardiaque minimum</string>
|
||||
<string name="activity_prefs_chart_max_heart_rate">Fréquence cardiaque maximum</string>
|
||||
<string name="activity_prefs_charts">Paramètres des graphiques</string>
|
||||
<string name="pref_invalid_frequency_message">Veuillez introduire une fréquence entre 87.5 et 108.0</string>
|
||||
<string name="pref_invalid_frequency_title">Fréquence non-valide</string>
|
||||
<string name="preferences_fm_frequency">Fréquence FM</string>
|
||||
<string name="preferences_led_color">Couleur de la DEL</string>
|
||||
<string name="controlcenter_change_fm_frequency">Changer la fréquence FM</string>
|
||||
<string name="controlcenter_change_led_color">Changer la couleur de la DEL</string>
|
||||
<string name="share_log_warning">Veuillez garder à l\'esprit que les fichiers logs de Gadgetbridge peuvent contenir des tas d\'informations personnelles, incluant entre autre des données relatives à la santé, des identifiants uniques (telles que des adresses MAC), des préférences musicales, etc. Pensez à modifier le fichier et retirer ces informations personnelles avant toute publication sur un rapport de bug public.</string>
|
||||
<string name="share_log">Partager les logs</string>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="mi3_night_mode_sunset">Au coucher du soleil</string>
|
||||
<string name="mi3_prefs_night_mode_summary">Diminuer la luminosité de l\'écran du bracelet automatiquement lorsqu\'il fait sombre</string>
|
||||
<string name="miband_fwinstaller_compatible_version">Version compatible</string>
|
||||
<string name="fwapp_install_device_not_ready">Le fichier ne peut pas être installé, l\'appareil n\'est pas prêt.</string>
|
||||
<string name="updating_firmware">Installation du micrologiciel…</string>
|
||||
<string name="activity_sleepchart_activity_and_sleep">Activité</string>
|
||||
<string name="weekstepschart_steps_a_week">Pas de la semaine</string>
|
||||
<string name="weeksleepchart_today_sleep_description">Sommeil aujourd\'hui, objectif : %1$s</string>
|
||||
<string name="weeksleepchart_sleep_a_week">Sommeil de la semaine</string>
|
||||
<string name="sleepchart_your_sleep">Sommeil</string>
|
||||
<string name="notif_battery_low_bigtext_number_of_charges">Nombre de charges : %s</string>
|
||||
<string name="notif_battery_low_bigtext_last_charge_time">Dernière charge : %s
|
||||
\n</string>
|
||||
<string name="installer_activity_wait_while_determining_status">Veuillez patienter pendant la détermination de l\'état de l\'installation…</string>
|
||||
<string name="pbw_install_handler_hw_revision_mismatch">Impossible d\'installer le micrologiciel spécifié : il ne correspond pas à la version du matériel de votre Pebble.</string>
|
||||
<string name="pbw_install_handler_unable_to_install">Impossible d\'installer le ficher suivant : %1$s</string>
|
||||
<string name="installer_activity_unable_to_find_handler">Impossible de trouver un gestionnaire pour installer ce fichier.</string>
|
||||
<string name="cannot_connect">Impossible de se connecter : %1$s</string>
|
||||
<string name="controlcenter_start_activitymonitor">Votre activité (ALPHA)</string>
|
||||
<string name="dbaccess_error_executing">Erreur lors de l’exécution de %1$s\'</string>
|
||||
<string name="miband_prefs_fitness_goal">Objectif de pas par jour</string>
|
||||
<string name="user_feedback_miband_activity_data_transfer">Sur le point de transférer %1$s de données à partir de %2$s</string>
|
||||
<string name="user_feedback_miband_set_alarms_ok">Alarmes envoyées à l\'appareil.</string>
|
||||
<string name="user_feedback_miband_set_alarms_failed">Une erreur s\'est produite lors du paramétrage des alarmes, veuillez réessayer.</string>
|
||||
<string name="alarm_smart_wakeup">Réveil intelligent</string>
|
||||
<string name="alarm_sat_short">Sam</string>
|
||||
<string name="alarm_fri_short">Ven</string>
|
||||
<string name="alarm_thu_short">Jeu</string>
|
||||
<string name="alarm_wed_short">Mer</string>
|
||||
<string name="alarm_tue_short">Mar</string>
|
||||
<string name="alarm_mon_short">Lun</string>
|
||||
<string name="alarm_sun_short">Dim</string>
|
||||
<string name="title_activity_alarm_details">Détails des alarmes</string>
|
||||
<string name="controlcenter_start_configure_alarms">Configurer les alarmes</string>
|
||||
<string name="title_activity_set_alarm">Configurer les alarmes</string>
|
||||
<string name="title_activity_charts">Activité et Sommeil</string>
|
||||
<string name="control_center_cancel_to_stop_vibration">Annuler pour arrêter les vibrations.</string>
|
||||
<string name="control_center_find_lost_device">Trouver l\'appareil perdu</string>
|
||||
<string name="stats_y_axis_label">Pas par minute</string>
|
||||
<string name="stats_x_axis_label">Total de minutes</string>
|
||||
<string name="stats_title">Zones de vitesse</string>
|
||||
<string name="pref_screen_notification_profile_generic_social">Réseau social</string>
|
||||
<string name="pref_screen_notification_profile_generic_navigation">Navigation</string>
|
||||
<string name="pref_screen_notification_profile_generic_chat">Tchat</string>
|
||||
<string name="pref_screen_notification_profile_incoming_call">Notification d\'appels entrants</string>
|
||||
<string name="pref_screen_notification_profile_email">Notification par courriel</string>
|
||||
<string name="pref_screen_notification_profile_generic">Notification générique</string>
|
||||
<string name="pref_header_vibration_settings">Paramètres des vibrations</string>
|
||||
<string name="pref_screen_notification_profile_sms">Notification Texto</string>
|
||||
<string name="vibration_try">Essayer</string>
|
||||
<string name="vibration_profile_alarm_clock">Réveil</string>
|
||||
<string name="vibration_profile_ring">Sonnette</string>
|
||||
<string name="vibration_profile_waterdrop">Goute d\'eau</string>
|
||||
<string name="vibration_profile_medium">Moyen</string>
|
||||
<string name="vibration_profile_short">Court</string>
|
||||
<string name="vibration_profile_staccato">Saccadé</string>
|
||||
<string name="pref_screen_vibration_profile">Profil de vibration</string>
|
||||
<string name="sleep_activity_date_range">De %1$s à %2$s</string>
|
||||
<string name="busy_task_fetch_activity_data">Récupération des données d\'activité</string>
|
||||
<string name="initializing">Initialisation</string>
|
||||
<string name="pref_write_logfiles">Écrire des fichiers journaux</string>
|
||||
<string name="title_activity_sleepmonitor">Moniteur de sommeil</string>
|
||||
<string name="pref_header_vibration_count">Nombre de vibrations</string>
|
||||
<string name="miband_prefs_alias">Nom/Pseudo</string>
|
||||
<string name="candidate_item_device_image">Image de l\'appareil</string>
|
||||
<string name="discovery_note">Note :</string>
|
||||
<string name="discovery_connected_devices_hint">Mettez votre appareil en mode visible. Les appareils déjà connectés ne seront pas visibles. Sur Android 6 ou supérieur, vous devez activer la localisation (ex. GPS). Désactivez Privacy Guard pour Gadgetbridge, il pourrait stopper et redémarrer votre téléphone. Si votre appareil n\'est pas visible après 2 minutes, réessayez après avoir redémarré votre téléphone.</string>
|
||||
<string name="appinstaller_install">Installer</string>
|
||||
<string name="miband_pairing_tap_hint">Quand votre Mi Band vibre et clignote, appuyez dessus plusieurs fois d\'affilée.</string>
|
||||
<string name="miband_pairing_using_dummy_userdata">Aucune donnée utilisateur valide fournie, utilisation de données fictives pour le moment.</string>
|
||||
<string name="right">Droite</string>
|
||||
<string name="left">Gauche</string>
|
||||
<string name="other">Autre</string>
|
||||
<string name="female">Femme</string>
|
||||
<string name="male">Homme</string>
|
||||
<string name="preferences_miband_settings">Paramètres Mi Band / Amazfit</string>
|
||||
<string name="preferences_category_device_specific_settings">Paramètres spécifiques à l\'appareil</string>
|
||||
<string name="message_cannot_pair_no_mac">Aucune adresse MAC fournie, ne peut être appairé.</string>
|
||||
<string name="pairing_already_bonded">Déjà lié avec %1$s (%2$s), connexion…</string>
|
||||
<string name="pairing_in_progress">Création du lien en cours : %1$s (%2$s)</string>
|
||||
<string name="pairing_unable_to_pair_with">Impossible se s’appairer avec %1$s (%2$s)</string>
|
||||
<string name="pairing_creating_bond_with">Création d’un lien avec %1$s (%2$s)</string>
|
||||
<string name="pairing">Jumelage avec %s…</string>
|
||||
<string name="title_activity_mi_band_pairing">Appairer votre Mi Band</string>
|
||||
<string name="android_pairing_hint">Utiliser l\'appairage Bluetooth d\'Android pour jumeler l\'appareil.</string>
|
||||
<string name="title_activity_android_pairing">Appairer l\'appareil</string>
|
||||
<string name="action_discover">Connecter un nouvel appareil</string>
|
||||
<string name="discovery_start_scanning">Démarrer le scan</string>
|
||||
<string name="discovery_stop_scanning">Arrêter le scan</string>
|
||||
<string name="title_activity_discovery">Scanner les appareils</string>
|
||||
<string name="initialized">Initialisé</string>
|
||||
<string name="n_a">N.D.</string>
|
||||
<string name="app_install_info">Vous êtes sur le point d\'installer l\'application suivante :
|
||||
\n
|
||||
\n
|
||||
\n%1$s Version %2$s par %3$s
|
||||
\n</string>
|
||||
<string name="firmware_install_warning">VOUS TENTEZ D\'INSTALLER UN MICROLOGICIEL, PROCÉDEZ À VOS RISQUES ET PÉRILS.
|
||||
\n
|
||||
\n
|
||||
\nCe micrologiciel est pour la version de matériel : %s</string>
|
||||
<string name="installation_successful">Installé</string>
|
||||
<string name="installation_failed_">Échec de l\'installation</string>
|
||||
<string name="installing_binary_d_d">Installation du binaire %1$d/%2$d</string>
|
||||
<string name="gadgetbridge_running">Gadgetbridge est en fonctionnement</string>
|
||||
<string name="tap_a_device_to_connect">Tapez sur le périphérique pour le connecter</string>
|
||||
<string name="tap_connected_device_for_vibration">Cliquez sur connecter pour envoyer une vibration</string>
|
||||
<string name="tap_connected_device_for_activity">Cliquez sur l\'appareil pour ouvrir le gestionnaire d’activité</string>
|
||||
<string name="tap_connected_device_for_app_mananger">Cliquez sur l\'appareil pour ouvrir le gestionnaire d\'application</string>
|
||||
<string name="bluetooth_is_disabled_">Le Bluetooth est désactivé.</string>
|
||||
<string name="bluetooth_is_not_supported_">Le Bluetooth n\'est pas supporté.</string>
|
||||
<string name="this_is_a_test_notification_from_gadgetbridge">Ceci est un test de notification venant de Gadgetbridge</string>
|
||||
<string name="test_notification">Notification de test</string>
|
||||
<string name="test">Test</string>
|
||||
<string name="_unknown_">(inconnu)</string>
|
||||
<string name="unknown_state">État inconnu</string>
|
||||
<string name="connected">Connecté</string>
|
||||
<string name="connecting">Connexion en cours</string>
|
||||
<string name="not_connected">Non connecté</string>
|
||||
<string name="preferences_hplus_settings">Paramètres HPlus/Makibes</string>
|
||||
<string name="prefs_title_all_day_heart_rate">Mesure de la fréquence cardiaque toute la journée</string>
|
||||
<string name="pref_title_screentime">Durée d\'écran allumé</string>
|
||||
<string name="pref_title_timeformat">Format de l\'heure</string>
|
||||
<string name="pref_title_unit_system">Unités</string>
|
||||
<string name="pref_title_pebble_reconnect_attempts">Tentatives de reconnexion</string>
|
||||
<string name="pref_summary_pebble_always_ack_pebblekit">Ceci permettra aux messages envoyés à des apps tierces d\'être toujours reconnus immédiatement</string>
|
||||
<string name="pref_title_pebble_always_ack_pebblekit">ACK à l\'avance du PebbleKit</string>
|
||||
<string name="pref_summary_pebble_enable_applogs">Ceci permettra à Gadgetbridge de conserver les logs des Watch App (requiert une reconnexion)</string>
|
||||
<string name="pref_title_pebble_enable_applogs">Activer les logs des apps du bracelet</string>
|
||||
<string name="pref_summary_pebble_mtu_limit">Si votre Pebble 2/LE ne fonctionne pas correctement, essayez d\'activer cette option pour limiter le MTU (plage valide 20–512)</string>
|
||||
<string name="pref_title_pebble_mtu_limit">Limite du GATT MTU de Pebble 2/LE</string>
|
||||
<string name="pref_summary_pebble_forcele">Utiliser le support expérimental du LE pour toutes les Pebble au lieu du Bluetooth classique. Cela requiert le jumelage d\'une Pebble non LE, puis d\'une Pebble LE</string>
|
||||
<string name="pref_title_pebble_forcele">Toujours préférer le BLE</string>
|
||||
<string name="pref_title_pebble_forceuntested">Activer les fonctionnalités non-testées</string>
|
||||
<string name="pref_title_pebble_forceprotocol">Forcer le protocole de notification</string>
|
||||
<string name="toast_aqurired_networklocation">Emplacement obtenu</string>
|
||||
<string name="toast_enable_networklocationprovider">Veuillez activer la localisation réseau</string>
|
||||
<string name="pref_title_location_keep_uptodate">Garder l’emplacement à jour</string>
|
||||
<string name="pref_title_location_longitude">Longitude</string>
|
||||
<string name="pref_title_location_latitude">Latitude</string>
|
||||
<string name="pref_title_location_aquire">Obtenir l\'emplacement</string>
|
||||
<string name="pref_header_location">Emplacement</string>
|
||||
<string name="pref_pebble_privacy_mode_complete">Ne montre que l\'icône de notification</string>
|
||||
<string name="pref_pebble_privacy_mode_content">Déplace les notifications hors de l\'écran</string>
|
||||
<string name="pref_pebble_privacy_mode_off">Notifications normales</string>
|
||||
<string name="pref_title_pebble_privacy_mode">Mode privé</string>
|
||||
<string name="pref_summary_autoremove_notifications">Les notifications sont automatiquement effacées de la Pebble lorsqu\'elles sont rejetées sur l\'appareil Android</string>
|
||||
<string name="pref_title_autoremove_notifications">Effacer automatiquement les notifications rejetées</string>
|
||||
<string name="pref_summary_enable_calendar_sync">Envoyer les événements du calendrier sur la timeline</string>
|
||||
<string name="pref_title_enable_calendar_sync">Synchroniser le calendrier</string>
|
||||
<string name="pref_summary_sunrise_sunset">Envoyer les heures de lever et coucher du soleil dans l’historique Pebble en fonction de l\'emplacement</string>
|
||||
<string name="pref_title_sunrise_sunset">Lever et coucher de soleil</string>
|
||||
<string name="pref_header_pebble_timeline">Timeline Pebble</string>
|
||||
<string name="pref_summary_enable_pebblekit">Activer le support expérimental pour les applications Android utilisant PebbleKit</string>
|
||||
<string name="pref_title_enable_pebblekit">Permettre l\'accès aux applications tierces Android</string>
|
||||
<string name="pref_summary_enable_outgoing_call">Désactiver ceci empêchera la Pebble 2/LE de vibrer lors des appels sortants</string>
|
||||
<string name="pref_title_enable_outgoing_call">Support des appels sortants</string>
|
||||
<string name="pref_title_pebble_sync_morpheuz">Synchroniser Morpheuz</string>
|
||||
<string name="pref_title_pebble_sync_misfit">Synchroniser Misfit</string>
|
||||
<string name="pref_title_pebble_sync_health">Synchroniser Pebble Health</string>
|
||||
<string name="pref_title_pebble_activitytracker">Traqueur d\'activité préféré</string>
|
||||
<string name="pref_header_activitytrackers">Traqueurs d\'activité</string>
|
||||
<string name="pref_title_pebble_settings">Paramètres Pebble</string>
|
||||
<string name="pref_title_development_miaddr">Adresse Mi Band</string>
|
||||
<string name="pref_header_development">Options développeur</string>
|
||||
<string name="pref_title_canned_messages_set">Mise à jour Pebble</string>
|
||||
<string name="pref_title_canned_messages_dismisscall">Raccrocher</string>
|
||||
<string name="pref_title_canned_reply_suffix">Suffixe fréquent</string>
|
||||
<string name="pref_title_canned_replies">Réponses</string>
|
||||
<string name="pref_header_cannned_messages">Modèles de messages</string>
|
||||
<string name="pref_blacklist_calendars">Mettre des calendriers en liste noire</string>
|
||||
<string name="pref_blacklist">Applications bloquées</string>
|
||||
<string name="pref_call_privacy_mode_complete">Masquer le nom et le numéro</string>
|
||||
<string name="pref_call_privacy_mode_number">Masquer le numéro mais afficher le nom</string>
|
||||
<string name="pref_call_privacy_mode_name">Masquer le nom mais afficher le numéro</string>
|
||||
<string name="pref_call_privacy_mode_off">Afficher le nom et le numéro</string>
|
||||
<string name="pref_title_call_privacy_mode">Mode de confidentialité d\'appel</string>
|
||||
<string name="pref_header_privacy">Confidentialité</string>
|
||||
<string name="never">Jamais</string>
|
||||
<string name="when_screen_off">Quand l\'écran est éteint</string>
|
||||
<string name="always">Toujours</string>
|
||||
<string name="pref_summary_transliteration">Activez ceci si votre appareil ne supporte pas la police de caractères</string>
|
||||
<string name="pref_title_transliteration">Transcription</string>
|
||||
<string name="pref_summary_notification_filter">Les notifications non-sollicitées sont suspendues dans ce mode</string>
|
||||
<string name="pref_title_notification_filter">Ne Pas Déranger</string>
|
||||
<string name="pref_title_whenscreenon">…y compris quand l\'écran est allumé</string>
|
||||
<string name="pref_title_notifications_generic">Support des notifications génériques</string>
|
||||
<string name="pref_summary_notifications_pebblemsg">Support des applications qui envoient des notification à Pebble via PebbleKit.</string>
|
||||
<string name="pref_title_notifications_pebblemsg">Messages Pebble</string>
|
||||
<string name="pref_title_notifications_sms">Textos</string>
|
||||
<string name="pref_title_notifications_call">Appels téléphoniques</string>
|
||||
<string name="pref_title_notifications_repetitions">Répétitions</string>
|
||||
<string name="pref_header_notifications">Notifications</string>
|
||||
<string name="pref_summary_minimize_priority_on">L\'icône de la barre d\'état et la notification de l\'écran de verrouillage sont masquées</string>
|
||||
<string name="pref_summary_minimize_priority_off">L\'icône de la barre d\'état et la notification de l\'écran de verrouillage sont affichées</string>
|
||||
<string name="pref_title_minimize_priority">Masquer la notification de Gadgetbridge</string>
|
||||
<string name="pref_title_language">Langue</string>
|
||||
<string name="pref_theme_dark">Sombre</string>
|
||||
<string name="pref_theme_light">Clair</string>
|
||||
<string name="pref_title_theme">Thème</string>
|
||||
<string name="pref_summary_datetime_syctimeonconnect">Synchroniser l\'heure sur l\'appareil lors de la connexion, et lorsque l\'heure ou le fuseau horaire changent sur Android</string>
|
||||
<string name="pref_title_datetime_syctimeonconnect">Synchroniser l\'heure</string>
|
||||
<string name="pref_header_datetime">Date et heure</string>
|
||||
<string name="pref_default">Par défaut</string>
|
||||
<string name="pref_title_general_autostartonboot">Démarrer automatiquement</string>
|
||||
<string name="pref_title_general_autoconnectonbluetooth">Connecter votre appareil quand le Bluetooth est activé</string>
|
||||
<string name="pref_header_general">Paramètres généraux</string>
|
||||
<string name="title_activity_settings">Paramètres</string>
|
||||
<string name="miband_firmware_suggest_whitelist">Si vous désirez continuer malgré tout, et que tout fonctionne correctement par la suite, veuillez en informer les développeurs de Gadgetbridge pour demander l\'ajout du micrologiciel %s à leur liste blanche.</string>
|
||||
<string name="miband_firmware_known">Ce micrologiciel a été testé et est connu pour être compatible avec Gadgetbridge.</string>
|
||||
<string name="fw_multi_upgrade_notice">Vous êtes sur le point d\'installer les micrologiciels %1$s et %2$s à la place de ceux qui sont actuellement sur votre Mi Band.</string>
|
||||
<string name="fw_upgrade_notice">Vous êtes sur le point d\'installer le micrologiciel %s.</string>
|
||||
<string name="dbmanagementactivvity_cannot_access_export_path">Impossible d\'accéder au fichier d\'export. Merci de contacter les développeurs.</string>
|
||||
<string name="activity_db_management_merge_old_title">Effacer l\'ancienne base de données</string>
|
||||
<string name="activity_db_management_import_export_explanation">Les opérations sur la base de données ont utilisé le chemin suivant sur votre appareil.
|
||||
\nCe chemin est accessible par d\'autres applications Android ou par votre ordinateur.
|
||||
\nVotre base de données (ou celle que vous souhaitez importer) se trouvera ici :</string>
|
||||
<string name="title_activity_db_management">Gestion de base de données</string>
|
||||
<string name="action_db_management">Gestion de base de données</string>
|
||||
<string name="pref_summary_pebble_health_store_raw">Si coché, les données « brutes » sont stockées pour une interprétation ultérieure, augmentant la taille de la base de données.</string>
|
||||
<string name="title_activity_fw_app_insaller">Installateur d\'applications/firmware</string>
|
||||
<string name="title_activity_calblacklist">Calendriers sur liste noire</string>
|
||||
<string name="title_activity_appblacklist">Liste noire de notifications</string>
|
||||
<string name="app_move_to_top">Haut de page</string>
|
||||
<string name="app_configure">Configurer</string>
|
||||
<string name="appmanager_weather_install_provider">Installer l\'application de notification de la météo</string>
|
||||
<string name="appmanager_weather_deactivate">Désactiver l\'application météo</string>
|
||||
<string name="appmanager_weather_activate">Activer l\'application météo</string>
|
||||
<string name="appmanager_hrm_deactivate">Désactiver la mesure du rythme cardiaque</string>
|
||||
<string name="appmanager_hrm_activate">Activer la mesure du rythme cardiaque</string>
|
||||
<string name="appmanager_health_deactivate">Désactiver</string>
|
||||
<string name="appmanager_health_activate">Activer</string>
|
||||
<string name="appmanager_app_openinstore">Rechercher dans le magasin d’application Pebble</string>
|
||||
<string name="appmananger_app_reinstall">Réinstaller</string>
|
||||
<string name="appmananger_app_delete_cache">Supprimer et effacer du cache</string>
|
||||
<string name="appmananger_app_delete">Supprimer</string>
|
||||
<string name="appmanager_installed_watchfaces">Watchfaces installées</string>
|
||||
<string name="appmanager_installed_watchapps">Applis installées</string>
|
||||
<string name="appmanager_cached_watchapps_watchfaces">Applis en cache</string>
|
||||
<string name="title_activity_appmanager">Gestionnaire d\'application</string>
|
||||
<string name="title_activity_debug">Déboguer</string>
|
||||
<string name="controlcenter_snackbar_requested_screenshot">Capturer l\'écran de l\'appareil</string>
|
||||
<string name="controlcenter_snackbar_connecting">Connexion…</string>
|
||||
<string name="controlcenter_snackbar_disconnecting">Déconnexion</string>
|
||||
<string name="controlcenter_snackbar_need_longpress">Presser longuement l\'icône pour déconnecter</string>
|
||||
<string name="controlcenter_navigation_drawer_close">Fermer le tiroir de navigation</string>
|
||||
<string name="controlcenter_navigation_drawer_open">Ouvrir le tiroir de navigation</string>
|
||||
<string name="controlcenter_delete_device_name">Supprimer %1$s</string>
|
||||
<string name="controlcenter_delete_device">Supprimer l’appareil</string>
|
||||
<string name="controlcenter_disconnect">Déconnecter</string>
|
||||
<string name="controlcenter_take_screenshot">Prendre une capture d\'écran</string>
|
||||
<string name="controlcenter_find_device">Retrouver votre appareil perdu</string>
|
||||
<string name="controlcenter_fetch_activity_data">Synchroniser</string>
|
||||
<string name="action_donate">Faire un don</string>
|
||||
<string name="action_quit">Quitter</string>
|
||||
<string name="action_debug">Déboguer</string>
|
||||
<string name="action_settings">Paramètres</string>
|
||||
</resources>
|
@ -22,8 +22,8 @@
|
||||
<string name="title_activity_debug">Déboguer</string>
|
||||
<!--Strings related to AppManager-->
|
||||
<string name="title_activity_appmanager">Gestionnaire d\'application</string>
|
||||
<string name="appmanager_cached_watchapps_watchfaces">Apps en cache</string>
|
||||
<string name="appmanager_installed_watchapps">Apps installées</string>
|
||||
<string name="appmanager_cached_watchapps_watchfaces">Applis en cache</string>
|
||||
<string name="appmanager_installed_watchapps">Applis installées</string>
|
||||
<string name="appmanager_installed_watchfaces">Watchfaces installées</string>
|
||||
<string name="appmananger_app_delete">Supprimer</string>
|
||||
<string name="appmananger_app_delete_cache">Supprimer et effacer du cache</string>
|
||||
@ -50,7 +50,7 @@
|
||||
<string name="miband_firmware_unknown_warning">Ce micrologiciel n\'a pas été testé et peut ne pas être compatible avec Gadgetbridge.
|
||||
\n
|
||||
\nIl n\'est PAS conseillé de le flasher !</string>
|
||||
<string name="miband_firmware_suggest_whitelist">Si vous désirez continuer et que tout fonctionne correctement par la suite, veuillez en informer les développeurs de Gadgetbridge pour demander l\'ajout du micrologiciel %s à leur liste.</string>
|
||||
<string name="miband_firmware_suggest_whitelist">Si vous désirez continuer malgré tout, et que tout fonctionne correctement par la suite, veuillez en informer les développeurs de Gadgetbridge pour demander l\'ajout du micrologiciel %s à leur liste blanche.</string>
|
||||
<!--Strings related to Settings-->
|
||||
<string name="title_activity_settings">Paramètres</string>
|
||||
<string name="pref_header_general">Paramètres généraux</string>
|
||||
@ -129,9 +129,9 @@
|
||||
<string name="toast_enable_networklocationprovider">Veuillez activer la localisation réseau</string>
|
||||
<string name="toast_aqurired_networklocation">Emplacement obtenu</string>
|
||||
<string name="pref_title_pebble_forceprotocol">Forcer le protocole de notification</string>
|
||||
<string name="pref_summary_pebble_forceprotocol">Cette option force l\'utilisation du protocole de notification le plus récent selon votre version du micrologiciel. A VOS PROPRES RISQUES!</string>
|
||||
<string name="pref_title_pebble_forceuntested">Activer les fonctionnalités non-testées</string>
|
||||
<string name="pref_summary_pebble_forceuntested">Activer les fonctionnalités non-testées. A VOS PROPRES RISQUES !</string>
|
||||
<string name="pref_summary_pebble_forceprotocol">Cette option force l\'utilisation du protocole de notification le plus récent selon votre version du micrologiciel. À VOS PROPRES RISQUES ET PÉRILS !</string>
|
||||
<string name="pref_title_pebble_forceuntested">Activer les fonctionnalités non testées</string>
|
||||
<string name="pref_summary_pebble_forceuntested">Activer les fonctionnalités non testées. À VOS PROPRES RISQUES ET PÉRILS !</string>
|
||||
<string name="pref_title_pebble_forcele">Toujours préférer le BLE</string>
|
||||
<string name="pref_summary_pebble_forcele">Utiliser le support expérimental du LE pour toutes les Pebble au lieu du Bluetooth classique. Cela requiert le jumelage d\'une Pebble non LE, puis d\'une Pebble LE</string>
|
||||
<string name="pref_title_pebble_mtu_limit">Limite du GATT MTU de Pebble 2/LE</string>
|
||||
@ -218,7 +218,7 @@
|
||||
<string name="pref_screen_notification_profile_sms">Notification Texto</string>
|
||||
<string name="pref_header_vibration_settings">Paramètres des vibrations</string>
|
||||
<string name="pref_screen_notification_profile_generic">Notification générique</string>
|
||||
<string name="pref_screen_notification_profile_email">Notification des mails</string>
|
||||
<string name="pref_screen_notification_profile_email">Notification par courriel</string>
|
||||
<string name="pref_screen_notification_profile_incoming_call">Notification d\'appels entrants</string>
|
||||
<string name="pref_screen_notification_profile_generic_chat">Tchat</string>
|
||||
<string name="pref_screen_notification_profile_generic_navigation">Navigation</string>
|
||||
@ -265,7 +265,7 @@
|
||||
<string name="fwapp_install_device_not_ready">Le fichier ne peut pas être installé, l\'appareil n\'est pas prêt.</string>
|
||||
<string name="installhandler_firmware_name">%1$s: %2$s %3$s</string>
|
||||
<string name="miband_fwinstaller_compatible_version">Version compatible</string>
|
||||
<string name="miband_fwinstaller_untested_version">Version non-testée !</string>
|
||||
<string name="miband_fwinstaller_untested_version">Version non testée !</string>
|
||||
<string name="fwappinstaller_connection_state">Connexion à l\'appareil : %1$s</string>
|
||||
<string name="pbw_installhandler_pebble_firmware">Micrologiciel Pebble %1$s</string>
|
||||
<string name="pbwinstallhandler_correct_hw_revision">Version du matériel correcte</string>
|
||||
@ -327,7 +327,7 @@
|
||||
<string name="waiting_for_reconnect">En attente de reconnexion</string>
|
||||
<string name="activity_prefs_about_you">À propos de vous</string>
|
||||
<string name="activity_prefs_year_birth">Année de naissance</string>
|
||||
<string name="activity_prefs_gender">Genre</string>
|
||||
<string name="activity_prefs_gender">Sexe</string>
|
||||
<string name="activity_prefs_height_cm">Taille en cm</string>
|
||||
<string name="activity_prefs_weight_kg">Poids en kg</string>
|
||||
<string name="authenticating">Authentification</string>
|
||||
@ -346,7 +346,7 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="charts_legend_heartrate">Fréquence cardiaque</string>
|
||||
<string name="live_activity_heart_rate">Fréquence cardiaque</string>
|
||||
<string name="pref_title_pebble_health_store_raw">Stockez les enregistrements brut dans la base de données</string>
|
||||
<string name="pref_summary_pebble_health_store_raw">Si coché, les données \"brutes\" sont stockées pour une interprétation ultérieure, augmentant la taille de la base de données.</string>
|
||||
<string name="pref_summary_pebble_health_store_raw">Si coché, les données « brutes » sont stockées pour une interprétation ultérieure, augmentant la taille de la base de données.</string>
|
||||
<string name="action_db_management">Gestion de base de données</string>
|
||||
<string name="title_activity_db_management">Gestion de base de données</string>
|
||||
<string name="activity_db_management_import_export_explanation">Les opérations sur la base de données ont utilisé le chemin suivant sur votre appareil.
|
||||
@ -407,17 +407,17 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="discovery_dont_pair">Ne pas appairer</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Bip.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res, puis le fichier.gps. Votre montre redémarrera après installation du .fw.
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res, puis le fichier.gps.. Votre montre redémarrera après installation du .fw.
|
||||
\n
|
||||
\nNote : vous ne devez pas installer .res et .gps si ceux-ci sont identiques à ceux installés précédemment.
|
||||
\nNote : vous ne devez pas installer les fichiers .res et .gps si ceux-ci sont identiques à ceux installés précédemment.
|
||||
\n
|
||||
\nCONTINUEZ À VOS RISQUES !</string>
|
||||
\nCONTINUEZ À VOS RISQUES ET PÉRILS !</string>
|
||||
<string name="mi2_prefs_button_actions">Actions du bouton</string>
|
||||
<string name="mi2_prefs_button_actions_summary">Spécifier les actions par pression du bouton</string>
|
||||
<string name="mi2_prefs_button_press_count">Nombre de pressions du bouton</string>
|
||||
<string name="mi2_prefs_button_press_count_summary">Nombre d\'appuis sur le boutton pour envoyer l’Évènement 1. Appuyer de nouveau autant de fois créera l\'Évènement 2, etc.</string>
|
||||
<string name="mi2_prefs_button_press_broadcast">Message à envoyer</string>
|
||||
<string name="mi2_prefs_button_press_broadcast_summary">Message de diffusion envoyé avec l\'évènement. Le paramètre `button_id` est automatiquement ajouté à chaque message.</string>
|
||||
<string name="mi2_prefs_button_press_broadcast_summary">Message de diffusion envoyé avec l\'évènement. Le paramètre « button_id » est automatiquement ajouté à chaque message.</string>
|
||||
<string name="mi2_prefs_button_action">Activer action du bouton</string>
|
||||
<string name="mi2_prefs_button_action_summary">Activer action après nombre spécifié de pressions</string>
|
||||
<string name="mi2_prefs_button_action_vibrate">Activer la vibration du bracelet</string>
|
||||
@ -433,13 +433,13 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="pref_summary_pebble_enable_bgjs">Si activé, autorise l\'affichage de la météo, niveau de batterie, etc.</string>
|
||||
<string name="activity_web_view">Activité Web View</string>
|
||||
<string name="controlcenter_connect">Connexion…</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Cor.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res. Votre montre redémarrera après installation du fichier .fw.
|
||||
\n
|
||||
\nNote : Il n\'est pas nécessaire d\'installer le fichier .res si celui-ci est identique à celui installé précédemment.
|
||||
\n
|
||||
\nCONTINUEZ À VOS RISQUES !</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Cor.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res. Votre montre redémarrera après installation du .fw.
|
||||
\n
|
||||
\nNote : vous ne devez pas installer .res si celui-ci est identique à celui installé précédemment.
|
||||
\n
|
||||
\nCONTINUEZ À VOS RISQUES ET PÉRILS !</string>
|
||||
<string name="pref_title_charts_swipe">Permettre le balayage gauche/droite dans les graphiques d\'activité</string>
|
||||
<string name="automatic">Automatique</string>
|
||||
<string name="simplified_chinese">Chinois simplifié</string>
|
||||
@ -512,15 +512,15 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="menuitem_alipay">Alipay</string>
|
||||
<string name="blacklist_all_for_notifications">Mettre toutes les notifications en liste noire</string>
|
||||
<string name="whitelist_all_for_notifications">Mettre toutes les notifications en liste blanche</string>
|
||||
<string name="fw_upgrade_notice_miband3">Vous allez installer le micrologiciel %s dans votre Mi Band 3.
|
||||
\n
|
||||
\nAssurez-vous d\'installer d\'abord le fichier .fw, et ensuite le fichiers .res. Votre bracelet redémarrera après l\'installation du fichiers .fw.
|
||||
\n
|
||||
\nRemarque : Vous n\'avez pas besoin d\'installer le fichier .res si c\'est exactement le même que celui déjà installé.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS !</string>
|
||||
<string name="fw_upgrade_notice_miband3">Vous allez installer le micrologiciel %s dans votre Mi Band 3.
|
||||
\n
|
||||
\nAssurez-vous d\'installer d\'abord le fichier .fw, et ensuite le fichiers .res. Votre bracelet redémarrera après l\'installation du fichiers .fw.
|
||||
\n
|
||||
\nRemarque : Vous n\'avez pas besoin d\'installer le fichier .res si c\'est exactement le même que celui déjà installé.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS ET PÉRILS !</string>
|
||||
<string name="pref_title_pebble_gatt_clientonly">client GATT uniquement</string>
|
||||
<string name="pref_summary_pebble_gatt_clientonly">C\'est uniquement pour les Pebble 2 et expérimental, à essayer si vous avez des problèmes de connectivité</string>
|
||||
<string name="pref_summary_pebble_gatt_clientonly">Pour Pebble 2 seulement et expérimental, essayez seulement si vous avez des problèmes de connexion</string>
|
||||
<string name="prefs_screen_orientation">Orientation de l\'écran</string>
|
||||
<string name="pref_auto_fetch">Récupérer automatiquement les données d\'activité</string>
|
||||
<string name="pref_auto_fetch_summary">Récupération au déverrouillage de l\'écran. Fonctionne uniquement si un mécanisme de verrouillage est configuré !</string>
|
||||
@ -538,7 +538,7 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="menuitem_notifications">Notifications</string>
|
||||
<string name="menuitem_music">Musique</string>
|
||||
<string name="menuitem_more">Suite</string>
|
||||
<string name="controlcenter_change_led_color">Changer la couleur de la LED</string>
|
||||
<string name="controlcenter_change_led_color">Changer la couleur de la DEL</string>
|
||||
<string name="controlcenter_change_fm_frequency">Changer la fréquence FM</string>
|
||||
<string name="controlcenter_calibrate_device">Calibrer l\'appareil</string>
|
||||
<string name="pref_title_notifications_timeout">Durée minimum entre deux notifications</string>
|
||||
@ -546,10 +546,10 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="pref_summary_rtl">Cocher ceci si votre appareil n\'est pas compatible avec les langues \"droite-à-gauche\"</string>
|
||||
<string name="pref_rtl_max_line_length">Longueur max. d\'une ligne en mode Droite-à-Gauche</string>
|
||||
<string name="watch9_pairing_tap_hint">Lorsque votre bracelet vibre, secouez-le ou pressez son bouton.</string>
|
||||
<string name="notif_battery_low">%1$s niveau de batterie bas</string>
|
||||
<string name="notif_battery_low_extended">%1$s niveau de batterie base : %2$s</string>
|
||||
<string name="lack_of_sleep">Manque de sommeil: %1$s</string>
|
||||
<string name="overslept">Excès de sommeil: %1$s</string>
|
||||
<string name="notif_battery_low">%1$s batterie faible</string>
|
||||
<string name="notif_battery_low_extended">%1$s batterie faible : %2$s</string>
|
||||
<string name="lack_of_sleep">Manque de sommeil : %1$s</string>
|
||||
<string name="overslept">Excès de sommeil : %1$s</string>
|
||||
<string name="no_limit">Sans limite</string>
|
||||
<string name="seconds_5">5 secondes</string>
|
||||
<string name="seconds_10">10 secondes</string>
|
||||
@ -559,9 +559,9 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="minutes_5">5 minutes</string>
|
||||
<string name="minutes_10">10 minutes</string>
|
||||
<string name="minutes_30">30 minutes</string>
|
||||
<string name="lack_of_step">Manque d\'activité: %1$d</string>
|
||||
<string name="overstep">Trop d\'activité: %1$d</string>
|
||||
<string name="live_activity_max_heart_rate">Mesure cardiaque actuelle / maximum: %1$d / %2$d</string>
|
||||
<string name="lack_of_step">Manque d\'activité : %1$d</string>
|
||||
<string name="overstep">Trop d\'activité : %1$d</string>
|
||||
<string name="live_activity_max_heart_rate">Mesure cardiaque actuelle / maximum : %1$d / %2$d</string>
|
||||
<string name="you_slept">Vous avez dormi de %1$s à %2$s</string>
|
||||
<string name="you_did_not_sleep">Vous n\'avez pas dormi</string>
|
||||
<string name="mi3_prefs_band_screen_unlock_summary">Glisser le doigt vers le haut pour débloquer l\'écran du bracelet</string>
|
||||
@ -579,9 +579,9 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="mi3_night_mode_sunset">Au coucher du soleil</string>
|
||||
<string name="devicetype_watch9">Watch 9</string>
|
||||
<string name="watch9_time_minutes">Minutes:</string>
|
||||
<string name="watch9_time_hours">Heures:</string>
|
||||
<string name="watch9_time_seconds">Secondes:</string>
|
||||
<string name="watch9_time_minutes">Minutes :</string>
|
||||
<string name="watch9_time_hours">Heures :</string>
|
||||
<string name="watch9_time_seconds">Secondes :</string>
|
||||
<string name="watch9_calibration_hint">Régler l\'heure que votre appareil indique actuellement.</string>
|
||||
<string name="watch9_calibration_button">Calibrer</string>
|
||||
<string name="title_activity_watch9_pairing">Appairage de la Watch 9</string>
|
||||
@ -589,9 +589,9 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="preferences_rtl_settings">Support Droite-à-Gauche</string>
|
||||
<string name="share_log">Partager les logs</string>
|
||||
<string name="share_log_warning">Veuillez garder à l\'esprit que les fichiers logs de Gadgetbridge peuvent contenir des tas d\'informations personnelles, incluant entre autre des données relatives à la santé, des identifiants uniques (telles que des adresses MAC), des préférences musicales, etc. Pensez à modifier le fichier et retirer ces informations personnelles avant toute publication sur un rapport de bug public.</string>
|
||||
<string name="warning">Attention!</string>
|
||||
<string name="warning">Attention !</string>
|
||||
<string name="no_data">Pas de données</string>
|
||||
<string name="preferences_led_color">Couleur de la LED</string>
|
||||
<string name="preferences_led_color">Couleur de la DEL</string>
|
||||
<string name="preferences_fm_frequency">Fréquence FM</string>
|
||||
<string name="pref_invalid_frequency_title">Fréquence non-valide</string>
|
||||
<string name="pref_invalid_frequency_message">Veuillez introduire une fréquence entre 87.5 et 108.0</string>
|
||||
@ -601,7 +601,7 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="devicetype_roidmi3">Roidmi 3</string>
|
||||
<string name="pref_title_contextual_arabic">Arabe contextuel</string>
|
||||
<string name="pref_summary_contextual_arabic">A cocher pour activer le support \"Arabe contextuel\"</string>
|
||||
<string name="debugactivity_really_factoryreset_title">Confirmer la réinitialisation \?</string>
|
||||
<string name="debugactivity_really_factoryreset_title">Vraiment retourner aux paramètres d\'usine \?</string>
|
||||
<string name="debugactivity_really_factoryreset">Une réinitialisation effacera toutes les données de l\'appareil connecté (si supporté). Les appareils Xiaomi/Huami modifient également l\'adresse MAC Bluetooth, de sorte qu\'ils apparaissent comme de nouveaux appareils dans Gadgetbridge.</string>
|
||||
<string name="mi3_prefs_band_screen_unlock">Déverrouillage de l\'écran du Band</string>
|
||||
<string name="activity_type_exercise">Activité physique</string>
|
||||
@ -619,7 +619,7 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="filter_mode">Mode Filtre</string>
|
||||
<string name="mode_configuration">Mode Configuration</string>
|
||||
<string name="save_configuration">Sauvegarder la configuration</string>
|
||||
<string name="appwidget_not_connected">Non connecté, l’alarme n’est pas définie.</string>
|
||||
<string name="appwidget_not_connected">Non connecté, l\'alarme n\'est pas définie.</string>
|
||||
<string name="prefs_disconnect_notification">Notification de déconnexion</string>
|
||||
<string name="zetime_title_settings">Paramètres ZeTime</string>
|
||||
<string name="zetime_title_heartrate">Paramètres Fréquence Cardiaque</string>
|
||||
@ -633,7 +633,7 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="zetime_analog_mode_hands">Aiguilles seulement</string>
|
||||
<string name="zetime_analog_mode_handsandsteps">Aiguilles et Pas</string>
|
||||
<string name="zetime_activity_tracking">Suivi des Activités</string>
|
||||
<string name="zetime_activity_tracking_summary">"Activer le suivi des activités : comptera vos pas, etc."</string>
|
||||
<string name="zetime_activity_tracking_summary">Activer le suivi des activités : comptera vos pas, etc.</string>
|
||||
<string name="zetime_handmove_display_summary">Tourner le poignet pour activer ou désactiver l\'écran.</string>
|
||||
<string name="zetime_calories_type">Type de calories</string>
|
||||
<string name="zetime_calories_type_active">Seulement les calories brûlées activement</string>
|
||||
@ -667,23 +667,23 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="pref_screen_notification_profile_anti_loss">Alerte Anti-Perte</string>
|
||||
<string name="interval_fifteen_minutes">Toutes les 15 min</string>
|
||||
<string name="interval_forty_five_minutes">Toutes les 45 min</string>
|
||||
<string name="activity_prefs_calories_burnt">Objectif Quotidien : Calories Brulées</string>
|
||||
<string name="activity_prefs_distance_meters">Objectif Quotidien : Distance en mètres</string>
|
||||
<string name="activity_prefs_activetime_minutes">Objectif Quotidien : Temps d\'activité en minutes</string>
|
||||
<string name="activity_prefs_calories_burnt">Objectif quotidien : calories brulées</string>
|
||||
<string name="activity_prefs_distance_meters">Objectif quotidien : distance en mètres</string>
|
||||
<string name="activity_prefs_activetime_minutes">Objectif quotidien : temps d\'activité en minutes</string>
|
||||
<string name="devicetype_miscale2">Mi Scale 2</string>
|
||||
<string name="pref_title_support_voip_calls">Activer les applications d\'appel VoIP</string>
|
||||
<string name="title_activity_device_specific_settings">Paramètres spécifiques de l\'appareil</string>
|
||||
<string name="pref_title_authkey">Clé Auteur</string>
|
||||
<string name="pref_summary_authkey">Changez la clé auteur à une clé générale sur tous vos appareils Android sur lesquels vous souhaitez vous connecter. La précédente clé par défaut était 0123456789@ABCDE</string>
|
||||
<string name="devicetype_bfh16">BFH-16</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor2">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Cor 2.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res. Votre montre redémarrera après installation du .fw.
|
||||
\n
|
||||
\nNote : il n\'est pas nécessaire d\'installer le fichier .res si celui-ci est identique à celui installé précédemment.
|
||||
\n
|
||||
\nCONTINUEZ À VOS RISQUES !
|
||||
\n
|
||||
<string name="fw_upgrade_notice_amazfitcor2">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit Cor 2.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res. Votre montre redémarrera après installation du .fw.
|
||||
\n
|
||||
\nNote : il n\'est pas nécessaire d\'installer le fichier .res si celui-ci est identique à celui installé précédemment.
|
||||
\n
|
||||
\nCONTINUEZ À VOS RISQUES ET PÉRILS !
|
||||
\n
|
||||
\nNON TESTÉ, IL PEUT ÊTRE NÉCESSAIRE DE FLASHER UN MICROLOGICIEL BEATS_W SI LE NOM DE L\'APPAREIL EST « Amazfit Band 2 »</string>
|
||||
<string name="dutch">Néerlandais</string>
|
||||
<string name="turkish">Turc</string>
|
||||
@ -697,13 +697,13 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="pref_rtl_max_line_length_summary">Allonge ou raccourcis les lignes dans les textes écrits de droite à gauche</string>
|
||||
<string name="zetime_handmove_display">Mouvement de la main</string>
|
||||
<string name="devicetype_miband4">Mi Band 4</string>
|
||||
<string name="fw_upgrade_notice_miband4">Vous êtes sur le point d\'installer le firmware %s sur votre Mi Band 4.
|
||||
\n
|
||||
\nVeuillez vous assurez d\'installer le fichier .fw, et après que le fichier .res. Votre bracelet redémarrera après l\'installation du fichier .fw.
|
||||
\n
|
||||
\nRemarque : Vous n\'avez pas à installer .res s\'il est exactement le même que celui précédemment installé.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS !</string>
|
||||
<string name="fw_upgrade_notice_miband4">Vous êtes sur le point d\'installer le firmware %s sur votre Mi Band 4.
|
||||
\n
|
||||
\nVeuillez vous assurez d\'installer le fichier .fw, et après que le fichier .res. Votre bracelet redémarrera après l\'installation du fichier .fw.
|
||||
\n
|
||||
\nRemarque : Vous n\'avez pas à installer .res s\'il est exactement le même que celui précédemment installé.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS ET PÉRILS !</string>
|
||||
<string name="prefs_hr_alarm_activity">Alarme de la fréquence cardiaque durant une activité sportive</string>
|
||||
<string name="prefs_hr_alarm_low">Limite basse</string>
|
||||
<string name="prefs_hr_alarm_high">Limite haute</string>
|
||||
@ -715,11 +715,11 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="weeksleepchart_sleep_a_month">Sommeil par mois</string>
|
||||
<string name="menuitem_nfc">NFC</string>
|
||||
<string name="pref_title_use_custom_font">Utiliser une police personnalisée</string>
|
||||
<string name="activity_DB_test_export_message">Exportation de la base de données …</string>
|
||||
<string name="activity_DB_test_export_message">Exportation de la base de données…</string>
|
||||
<string name="activity_db_management_exportimport_label">Exporter et Importer</string>
|
||||
<string name="widget_steps_label">Pas : %1$02d</string>
|
||||
<string name="widget_listing_label">État et alarmes</string>
|
||||
<string name="widget_set_alarm_after">Régler l’alarme après :</string>
|
||||
<string name="widget_listing_label">Statuts et Alarmes</string>
|
||||
<string name="widget_set_alarm_after">Définir l\'alarme après :</string>
|
||||
<string name="widget_5_minutes">5 minutes</string>
|
||||
<string name="widget_10_minutes">10 minutes</string>
|
||||
<string name="widget_20_minutes">20 minutes</string>
|
||||
@ -728,21 +728,21 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="pref_display_add_device_fab_off">Visible uniquement si aucun appareil n\'est ajouté</string>
|
||||
<string name="prefs_find_phone_duration">Durée de la sonnerie en secondes</string>
|
||||
<string name="maximum_duration">Durée</string>
|
||||
<string name="pref_charts_range_on">La portée des graphs est réglée sur un mois</string>
|
||||
<string name="pref_charts_range_off">La portée des graphs est réglée sur une semaine</string>
|
||||
<string name="pref_charts_range_on">Gamme des graphiques positionnée sur un mois</string>
|
||||
<string name="pref_charts_range_off">Gamme des graphiques positionnée sur une semaine</string>
|
||||
<string name="devicetype_mijia_lywsd02">Mijia Smart Clock</string>
|
||||
<string name="pref_summary_expose_hr">Permettre aux autres applis d\'accéder aux données de fréquence cardiaque en temps réel lorsque Gadgetbridge est connecté</string>
|
||||
<string name="pref_title_expose_hr">Accès tiers fréq. cardiaque</string>
|
||||
<string name="pref_summary_use_custom_font">À activer si votre appareil a une police spéciale embarquée pour prendre en charge les émoticônes</string>
|
||||
<string name="pref_summary_use_custom_font">Activer ceci afin d’afficher les émojis si votre appareil a un micrologiciel de police personnalisée</string>
|
||||
<string name="activity_db_management_autoexport_explanation">L\'export automatique des données est réglé vers :</string>
|
||||
<string name="activity_db_management_autoexport_label">Export auto</string>
|
||||
<string name="activity_DB_ExportButton">Export de données</string>
|
||||
<string name="activity_DB_import_button">Import de données</string>
|
||||
<string name="activity_DB_test_export_button">Lancer l\'export maintenant</string>
|
||||
<string name="activity_DB_delete_legacy_button">Supprimer les anciennes données</string>
|
||||
<string name="activity_db_management_autoexport_label">Exportation automatique</string>
|
||||
<string name="activity_DB_ExportButton">Exporter la base de données</string>
|
||||
<string name="activity_DB_import_button">Importer la base de données</string>
|
||||
<string name="activity_DB_test_export_button">Lancer immédiatement l\'exportation automatique</string>
|
||||
<string name="activity_DB_delete_legacy_button">Supprimer l\'ancienne base de données</string>
|
||||
<string name="activity_DB_empty_button">Vider la base de données</string>
|
||||
<string name="activity_db_management_empty_DB">Vider la base de données</string>
|
||||
<string name="activity_db_management_empty_db_warning">Attention ! Ce bouton détruit votre base de données et réinitialise.</string>
|
||||
<string name="activity_db_management_empty_db_warning">Attention ! En cliquant sur ce bouton, vous supprimerez toutes vos données et recommencerez à zéro.</string>
|
||||
<string name="appwidget_sleep_alarm_widget_label">Réveil</string>
|
||||
<string name="widget_sleep_label">Sommeil : %1$s</string>
|
||||
<plurals name="widget_alarm_target_hours">
|
||||
@ -770,23 +770,23 @@ Temps de sommeil préféré en heures</string>
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS !</string>
|
||||
<string name="devicetype_amazfit_gtr">Amazfit GTR</string>
|
||||
<string name="fw_upgrade_notice_amazfitgtr">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit GTR.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res et enfin le fichier .gps. Votre montre redémarrera après installation du fichier .fw.
|
||||
\n
|
||||
\nNote : vous n\'avez pas à installer les fichiers .res et .gps s\'ils sont exactement les mêmes que ceux installés précédemment.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS !</string>
|
||||
<string name="fw_upgrade_notice_amazfitgtr">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit GTR.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res et enfin le fichier .gps. Votre montre redémarrera après installation du fichier .fw.
|
||||
\n
|
||||
\nNote : vous n\'avez pas à installer les fichiers .res et .gps s\'ils sont exactement les mêmes que ceux installés précédemment.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS ET PÉRILS !</string>
|
||||
<string name="pref_title_chart_heartrate_color">Couleur du rythme cardiaque</string>
|
||||
<string name="pref_title_chart_sleep_rolling_24_hour">Plage de sommeil</string>
|
||||
<string name="devicetype_amazfit_gts">Amazfit GTS</string>
|
||||
<string name="fw_upgrade_notice_amazfitgts">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit GTS.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res et enfin le fichier .gps. Votre montre redémarrera après installation du fichier .fw.
|
||||
\n
|
||||
\nNote : vous n\'avez pas à installer les fichiers .res et .gps s\'ils sont exactement les mêmes que ceux installés précédemment.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS !</string>
|
||||
<string name="fw_upgrade_notice_amazfitgts">Vous êtes sur le point d\'installer le micrologiciel %s sur votre Amazfit GTS.
|
||||
\n
|
||||
\nVeuillez installer le fichier .fw, puis le fichier .res et enfin le fichier .gps. Votre montre redémarrera après installation du fichier .fw.
|
||||
\n
|
||||
\nNote : vous n\'avez pas à installer les fichiers .res et .gps s\'ils sont exactement les mêmes que ceux installés précédemment.
|
||||
\n
|
||||
\nÀ VOS RISQUES ET PÉRILS ET PÉRILS !</string>
|
||||
<string name="devicetype_qhybrid">Fossil Q Hybrid</string>
|
||||
<string name="preferences_qhybrid_settings">Paramètres hybrides Q</string>
|
||||
<string name="watch_not_connected">Montre non connectée</string>
|
||||
@ -829,4 +829,21 @@ Temps de sommeil préféré en heures</string>
|
||||
<string name="find_lost_device_you_found_it">Trouvé !</string>
|
||||
<string name="pref_title_force_white_color_scheme">Forcer le noir sur le blanc</string>
|
||||
<string name="pref_summary_force_white_color_scheme">Utile si votre montre a les mains noires</string>
|
||||
<string name="pref_title_lower_button_function">Bouton inférieur</string>
|
||||
<string name="pref_title_middle_button_function">Bouton du milieu</string>
|
||||
<string name="pref_title_upper_button_function">Bouton supérieur</string>
|
||||
<string name="hr_appname_commute">Trajet</string>
|
||||
<string name="hr_appname_stopwatch">Chronomètre</string>
|
||||
<string name="hr_appname_workout">Entraînement</string>
|
||||
<string name="hr_appname_wellness">Bien-être</string>
|
||||
<string name="notification_channel_high_priority_name">Priorité haute des notifications Gadgetbridge</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="find_my_phone_notification">Trouver mon téléphone</string>
|
||||
<string name="pref_title_vibration_strength">Puissance du vibreur</string>
|
||||
<string name="pref_title_relax_firmware_checks">Activez cette option si vous souhaitez flasher un microprogramme qui n\'est pas destiné à votre appareil (à vos propres risques)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Assouplir les contrôles des microprogrammes</string>
|
||||
<string name="pref_summary_custom_deviceicon">Afficher une icône de notification Android spécifique à l\'appareil à la place de l\'icône Gadgetbridge lors de la connexion</string>
|
||||
<string name="pref_title_custom_deviceicon">Afficher l’icône de notification spécifique à l’appareil</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Widget traçant des cercles</string>
|
||||
<string name="pref_header_auto_fetch">Récupération automatique</string>
|
||||
</resources>
|
@ -849,4 +849,10 @@
|
||||
<string name="pref_title_upper_button_function">כפתור עליון</string>
|
||||
<string name="pref_title_middle_button_function">כפתור אמצעי</string>
|
||||
<string name="pref_title_lower_button_function">כפתור תחתון</string>
|
||||
<string name="pref_title_vibration_strength">עצמת הרטט</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="pref_title_relax_firmware_checks">יש להפעיל זאת אם מטרתך היא לצרוב קושחה שאינה מיועדת להתקן שלך (באחריותך הבלעדית)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">הפחתת בדיקות חומרה</string>
|
||||
<string name="pref_header_auto_fetch">קבלה אוטומטית</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">ציור עיגולי וידג׳טים</string>
|
||||
</resources>
|
@ -383,7 +383,7 @@
|
||||
<string name="find_device_you_found_it">Trovato!</string>
|
||||
<string name="find_lost_device_you_found_it">Trovato!</string>
|
||||
<string name="miband2_prefs_timeformat">Mi2: Formato dell\'orario</string>
|
||||
<string name="mi2_fw_installhandler_fw53_hint">E\' necessario installare la verione %1$s prima di installare questo firmware!</string>
|
||||
<string name="mi2_fw_installhandler_fw53_hint">È necessario installare la verione %1$s prima di installare questo firmware!</string>
|
||||
<string name="mi2_enable_text_notifications">Notifiche</string>
|
||||
<string name="mi2_enable_text_notifications_summary">Richiede firmware versione minima 1.9.1.28 e Mili_pro.ft* installati.</string>
|
||||
<string name="off">spento</string>
|
||||
@ -826,4 +826,19 @@
|
||||
<string name="qhybrid_second_timezone_offset_relative_to_utc">compensazione del secondo fuso orario rispetto a UTC</string>
|
||||
<string name="qhybrid_offset_timezone">compensazione del fuso orario di</string>
|
||||
<string name="qhybrid_offset_time_by">compensazione dell\'ora di</string>
|
||||
<string name="pref_title_lower_button_function">Pulsante inferiore</string>
|
||||
<string name="pref_title_middle_button_function">Pulsante centrale</string>
|
||||
<string name="pref_title_upper_button_function">Pulsante superiore</string>
|
||||
<string name="hr_appname_commute">Commute</string>
|
||||
<string name="hr_appname_stopwatch">Cronometro</string>
|
||||
<string name="hr_appname_workout">Allenamento</string>
|
||||
<string name="hr_appname_wellness">Benessere</string>
|
||||
<string name="qhybrid_use_activity_hand_as_notification_counter">utilizzare la mano di attività come contatore di notifica</string>
|
||||
<string name="qhybrid_overwrite_buttons">sovrascrivere i pulsanti</string>
|
||||
<string name="notification_channel_high_priority_name">Notifiche di Gadgetbridge ad alta priorità</string>
|
||||
<string name="find_my_phone_notification">Trova il mio telefono</string>
|
||||
<string name="pref_title_vibration_strength">Resistenza alle vibrazioni</string>
|
||||
<string name="pref_title_relax_firmware_checks">Attivare questo se si vuole far lampeggiare un firmware non destinato al proprio dispositivo (a proprio rischio e pericolo)</string>
|
||||
<string name="pref_summary_custom_deviceicon">Mostra l\'icona di notifica di un dispositivo specifico per Android invece l\'icona di Gadgetbridge quando è connesso</string>
|
||||
<string name="pref_title_custom_deviceicon">Mostra l\'icona di notifica specifica del dispositivo</string>
|
||||
</resources>
|
@ -836,4 +836,24 @@
|
||||
<string name="hr_widget_battery">Batteri</string>
|
||||
<string name="hr_widget_weather">Vær</string>
|
||||
<string name="hr_widget_nothing">Ingenting</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="hr_appname_wellness">Velvære</string>
|
||||
<string name="hr_appname_workout">Treningsøkt</string>
|
||||
<string name="pref_title_custom_deviceicon">Vis enhetsspesifikt merknadsikon</string>
|
||||
<string name="hr_appname_stopwatch">Stoppeklokke</string>
|
||||
<string name="pref_title_lower_button_function">Nedre knapp</string>
|
||||
<string name="pref_title_middle_button_function">Midtknapp</string>
|
||||
<string name="pref_title_upper_button_function">Øvre knapp</string>
|
||||
<string name="find_lost_device_you_found_it">Fant den!</string>
|
||||
<string name="pref_title_vibration_strength">Vibrasjonsstyrke</string>
|
||||
<string name="hr_appname_commute">Pendle</string>
|
||||
<string name="notification_channel_high_priority_name">Gadgetbridge-varsler har høy prioritet</string>
|
||||
<string name="pref_summary_force_white_color_scheme">Nyttig hvis klokken din har mørke hender</string>
|
||||
<string name="pref_title_force_white_color_scheme">Tving svart på hvitt fargevalg</string>
|
||||
<string name="find_my_phone_notification">Finn min telefon</string>
|
||||
<string name="pref_title_relax_firmware_checks">Aktiver dette hvis du vil blinke en fastvare som ikke er beregnet på enheten din (på egen risiko)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Slapp av firmwarekontroller</string>
|
||||
<string name="pref_summary_custom_deviceicon">Vis et enhetsspesifikt Android-varslingsikon i stedet for Gadgetbridge-ikonet når du er tilkoblet</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Tegn miniprogramssirkler</string>
|
||||
<string name="pref_header_auto_fetch">Hent automatisk</string>
|
||||
</resources>
|
@ -847,4 +847,10 @@
|
||||
<string name="pref_title_upper_button_function">Bovenste knop</string>
|
||||
<string name="pref_title_middle_button_function">Middelste knop</string>
|
||||
<string name="pref_title_lower_button_function">Onderste knop</string>
|
||||
<string name="pref_title_vibration_strength">Trillingssterkte</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="pref_title_relax_firmware_checks">Schakel dit in als u een firmware wilt flashen die niet voor uw apparaat bedoeld is (op eigen risico)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Ontspannen firmwarecontroles</string>
|
||||
<string name="pref_header_auto_fetch">Automatisch ophalen</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Teken widget cirkels</string>
|
||||
</resources>
|
@ -836,4 +836,20 @@
|
||||
<string name="hr_widget_weather">Pogoda</string>
|
||||
<string name="hr_widget_nothing">Nic</string>
|
||||
<string name="find_lost_device_you_found_it">Odnaleziono!</string>
|
||||
<string name="find_my_phone_notification">Znajdź mój telefon</string>
|
||||
<string name="pref_title_custom_deviceicon">Pokaż specyficzną dla urządzenia ikonę powiadomienia</string>
|
||||
<string name="hr_widget_active_minutes">Minuty aktywności</string>
|
||||
<string name="pref_title_force_white_color_scheme">Wymuś schemat kolorów czarno na białym</string>
|
||||
<string name="pref_summary_force_white_color_scheme">Użyteczne, jeśli twój zegarek ma ciemne wskazówki</string>
|
||||
<string name="notification_channel_high_priority_name">Powiadomienia Gadgetbridge o wysokim priorytecie</string>
|
||||
<string name="pref_summary_custom_deviceicon">Pokaż specyficzną dla urządzenia ikonę powiadomienia zamiast ikony Gadgetbridge, gdy połączono</string>
|
||||
<string name="hr_appname_workout">Trening</string>
|
||||
<string name="hr_appname_stopwatch">Stoper</string>
|
||||
<string name="pref_title_upper_button_function">Górny przycisk</string>
|
||||
<string name="pref_title_middle_button_function">Środkowy przycisk</string>
|
||||
<string name="pref_title_lower_button_function">Dolny przycisk</string>
|
||||
<string name="pref_title_vibration_strength">Siła wibracji</string>
|
||||
<string name="devicetype_amazfit_bips"></string>
|
||||
<string name="pref_title_relax_firmware_checks">Włącz to, jeśli chcesz błyskać oprogramowaniem sprzętowym, które nie jest przeznaczone dla Twojego urządzenia (na własne ryzyko)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Zrelaksuj kontrolę oprogramowania sprzętowego</string>
|
||||
</resources>
|
@ -859,4 +859,10 @@
|
||||
<string name="pref_title_upper_button_function">Botão superior</string>
|
||||
<string name="pref_title_middle_button_function">Botão do meio</string>
|
||||
<string name="pref_title_lower_button_function">Botão inferior</string>
|
||||
<string name="pref_title_vibration_strength">Intensidade da vibração</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="pref_title_relax_firmware_checks">Habilite isso se você deseja instalar um firmware não destinado para seu dispositivo (a seu próprio risco)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Verificações de firmware relaxadas</string>
|
||||
<string name="pref_header_auto_fetch">Coletar automaticamente</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Desenhar círculos de widget</string>
|
||||
</resources>
|
File diff suppressed because it is too large
Load Diff
@ -67,7 +67,7 @@
|
||||
<string name="pref_title_canned_replies">Відповіді</string>
|
||||
<string name="pref_title_canned_reply_suffix">Загальний суфікс</string>
|
||||
<string name="pref_header_development">Параметри для розробників</string>
|
||||
<string name="pref_title_development_miaddr">Адреса Mi Band</string>
|
||||
<string name="pref_title_development_miaddr">Адреса Mi-Band</string>
|
||||
<string name="pref_title_pebble_settings">Параметри Pebble</string>
|
||||
<string name="pref_header_activitytrackers">Трекер активності</string>
|
||||
<string name="pref_title_pebble_activitytracker">Бажаний трекер активності</string>
|
||||
@ -117,7 +117,7 @@
|
||||
<string name="title_activity_mi_band_pairing">Створення пари з Вашим Mi Band</string>
|
||||
<string name="message_cannot_pair_no_mac">Немає MAC-адресу, не вдалося створити пару.</string>
|
||||
<string name="preferences_category_device_specific_settings">Параметри специфічні для пристрою</string>
|
||||
<string name="preferences_miband_settings">Параметри Mi—Band / Amazfit</string>
|
||||
<string name="preferences_miband_settings">Параметри Mi-Band / Amazfit</string>
|
||||
<string name="male">Чоловіча</string>
|
||||
<string name="female">Жіноча</string>
|
||||
<string name="other">Інше</string>
|
||||
@ -145,9 +145,9 @@
|
||||
<string name="vibration_profile_alarm_clock">Будильник</string>
|
||||
<string name="miband_prefs_vibration">Вібрація</string>
|
||||
<string name="pref_screen_notification_profile_sms">SMS-сповіщення</string>
|
||||
<string name="pref_header_vibration_settings">Параметри вібровідгуку</string>
|
||||
<string name="pref_header_vibration_settings">Параметри вібрації</string>
|
||||
<string name="pref_screen_notification_profile_generic">Загальні сповіщення</string>
|
||||
<string name="pref_screen_notification_profile_incoming_call">Сповіщення під час вхідного дзвінку</string>
|
||||
<string name="pref_screen_notification_profile_incoming_call">Сповіщення вхідного дзвінка</string>
|
||||
<string name="pref_screen_notification_profile_generic_chat">Чат</string>
|
||||
<string name="pref_screen_notification_profile_generic_navigation">Навігація</string>
|
||||
<string name="pref_screen_notification_profile_generic_social">Соціальні мережі</string>
|
||||
@ -204,7 +204,7 @@
|
||||
<string name="weeksteps_today_steps_description">Кроків сьогодні, мета: %1$s</string>
|
||||
<string name="pref_title_dont_ack_transfer">Не передавати дані про активність</string>
|
||||
<string name="pref_summary_dont_ack_transfers">Якщо дані не будуть передані на пристрій, пристрій не буде очищений. Корисно, якщо Gadgetbridge використовується разом з іншими додатками.</string>
|
||||
<string name="pref_summary_keep_data_on_device">Дозволяє лишити дані на Mi-браслеті після синхронізації. Зазвичай використовується, якщо GB працює ще з іншими додатками.</string>
|
||||
<string name="pref_summary_keep_data_on_device">Дозволяє залишити дані на Mi-Band після синхронізації. Зазвичай використовується, якщо GB працює разом з іншими додатками.</string>
|
||||
<string name="live_activity_steps_history">Історія кроків</string>
|
||||
<string name="live_activity_current_steps_per_minute">Поточні кроки/хв</string>
|
||||
<string name="live_activity_total_steps">Загалом кроків</string>
|
||||
|
@ -41,19 +41,19 @@
|
||||
<string name="title_activity_calblacklist">阻止记录</string>
|
||||
<string name="title_activity_fw_app_insaller">FW/App 安装器</string>
|
||||
<string name="fw_upgrade_notice">您即将安装 %s 。</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip">即将在您的米动手表青春版(Amazfit Bip)上安装固件 %s 。
|
||||
\n
|
||||
\n请确保安装.fw文件,然后安装.res文件,最后安装.gps文件。 安装.fw文件后,手表将重新启动。
|
||||
\n
|
||||
\n注意:如果这些文件与之前安装的完全一样,则不必安装.res和.gps文件。
|
||||
\n
|
||||
<string name="fw_upgrade_notice_amazfitbip">即将在您的华米手表青春版(Amazfit Bip)上安装固件 %s 。
|
||||
\n
|
||||
\n请确保安装.fw文件,然后安装.res文件,最后安装.gps文件。 安装.fw文件后,手表将重新启动。
|
||||
\n
|
||||
\n注意:如果这些文件与之前安装的完全一样,则不必安装.res和.gps文件。
|
||||
\n
|
||||
\n***继续需要您自担风险!</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor">您即将在您的米动手环(Amazfit Cor)上安装固件 %s 。
|
||||
\n
|
||||
\n请确保安装了 .fw 文件,然后安装 .rec 文件。 安装 .fw 文件后,手表将重新启动。
|
||||
\n
|
||||
\n注意:如果这些文件与之前安装的完全一样,则不必安装 .res 。
|
||||
\n
|
||||
<string name="fw_upgrade_notice_amazfitcor">您即将在您的华米手环(Amazfit Cor)上安装固件 %s 。
|
||||
\n
|
||||
\n请确保安装了 .fw 文件,然后安装 .rec 文件。 安装 .fw 文件后,手表将重新启动。
|
||||
\n
|
||||
\n注意:如果这些文件与之前安装的完全一样,则不必安装 .res 。
|
||||
\n
|
||||
\n您需要自行承担风险!</string>
|
||||
<string name="fw_multi_upgrade_notice">您即将安装固件 %1$s 和 %2$s,代替当前在小米手环上的固件。</string>
|
||||
<string name="miband_firmware_known">该固件已经过测试,并且已知与 Gadgetbridge 兼容。</string>
|
||||
@ -197,7 +197,7 @@
|
||||
<string name="pairing_already_bonded">已与 %1$s (%2$s) 绑定,正在连接…</string>
|
||||
<string name="message_cannot_pair_no_mac">没有 MAC 地址通过, 不能配对。</string>
|
||||
<string name="preferences_category_device_specific_settings">设备特定设置</string>
|
||||
<string name="preferences_miband_settings">小米手环/米动手环设置</string>
|
||||
<string name="preferences_miband_settings">小米手环/华米手环设置</string>
|
||||
<string name="male">男</string>
|
||||
<string name="female">女</string>
|
||||
<string name="other">其它</string>
|
||||
@ -449,8 +449,8 @@
|
||||
<string name="devicetype_unknown">未知设备</string>
|
||||
<string name="devicetype_miband">小米手环</string>
|
||||
<string name="devicetype_miband2">小米手环2</string>
|
||||
<string name="devicetype_amazfit_bip">米动手表青春版</string>
|
||||
<string name="devicetype_amazfit_cor">米动手环</string>
|
||||
<string name="devicetype_amazfit_bip">华米手表青春版</string>
|
||||
<string name="devicetype_amazfit_cor">华米手环</string>
|
||||
<string name="pref_title_weather">天气</string>
|
||||
<string name="vibration_profile_waterdrop">水滴</string>
|
||||
<string name="devicetype_test">测试设备</string>
|
||||
@ -684,14 +684,14 @@
|
||||
<string name="pref_title_authkey">认证密钥</string>
|
||||
<string name="pref_summary_authkey">将您想要连接的所有 Android 设备上的认证密钥更改为通用的密钥。默认所有设备的密钥是 0123456789@ABCDE</string>
|
||||
<string name="devicetype_bfh16">BFH-16</string>
|
||||
<string name="fw_upgrade_notice_amazfitcor2">您即将在米动手环2(Amazfit Cor 2)上安装 %s 版本的固件
|
||||
\n
|
||||
\n请确保先安装 .fw 文件,再安装 .res 文件。您的手环将会在安装了 .fw 文件后重启
|
||||
\n
|
||||
\n备注:如果您安装的 .res 文件和之前相同,则无需安装 .res 文件
|
||||
\n
|
||||
\n风险自担!
|
||||
\n
|
||||
<string name="fw_upgrade_notice_amazfitcor2">您即将在华米手环2(Amazfit Cor 2)上安装 %s 版本的固件
|
||||
\n
|
||||
\n请确保先安装 .fw 文件,再安装 .res 文件。您的手环将会在安装了 .fw 文件后重启
|
||||
\n
|
||||
\n备注:如果您安装的 .res 文件和之前相同,则无需安装 .res 文件
|
||||
\n
|
||||
\n风险自担!
|
||||
\n
|
||||
\n此功能未经测试,如果您的设备名为“Amazfit Band 2”,您可能需要刷入 BEATS_W 固件</string>
|
||||
<string name="dutch">荷兰语</string>
|
||||
<string name="turkish">土耳其语</string>
|
||||
@ -701,7 +701,7 @@
|
||||
<string name="thai">泰语</string>
|
||||
<string name="vietnamese">越南语</string>
|
||||
<string name="portuguese">葡萄牙语</string>
|
||||
<string name="devicetype_amazfit_cor2">米动手环2</string>
|
||||
<string name="devicetype_amazfit_cor2">华米手环2</string>
|
||||
<string name="devicetype_miband4">小米手环4</string>
|
||||
<string name="fw_upgrade_notice_miband4">您即将在您的的小米手环4上安装 %s 固件。
|
||||
\n
|
||||
@ -756,27 +756,27 @@
|
||||
<string name="activity_error_no_app_for_gpx">若需要查看活动轨迹,请安装一个能查看 GPX 文件的应用。</string>
|
||||
<string name="preferences_makibes_hr3_settings">Makibes HR3 设置</string>
|
||||
<string name="devicetype_makibes_hr3">Makibes HR3</string>
|
||||
<string name="devicetype_amazfit_bip_lite">米动手表青春版 Lite</string>
|
||||
<string name="devicetype_amazfit_bip_lite">华米手表青春版 Lite</string>
|
||||
<string name="prefs_find_phone">查找手机</string>
|
||||
<string name="prefs_enable_find_phone">启用查找手机</string>
|
||||
<string name="prefs_find_phone_summary">使用您的手环以在手机上播放铃声。</string>
|
||||
<string name="prefs_find_phone_duration">铃声将持续数秒</string>
|
||||
<string name="maximum_duration">持续</string>
|
||||
<string name="discovery_need_to_enter_authkey">此设备需要认证密钥,请在设备上长按以输入密钥。具体请阅读 Wiki 。</string>
|
||||
<string name="fw_upgrade_notice_amazfitbip_lite">您即将在米动手表青春版 Lite(Amazfit Bip Lite)上安装 %s 版本的固件
|
||||
\n
|
||||
\n请确保先安装 .fw 文件,再安装 .res 文件。您的手环将会在安装了 .fw 文件后重启
|
||||
\n
|
||||
\n备注:如果您安装的 .res 文件和之前相同,则无需安装 .res 文件
|
||||
\n
|
||||
<string name="fw_upgrade_notice_amazfitbip_lite">您即将在华米手表青春版 Lite(Amazfit Bip Lite)上安装 %s 版本的固件
|
||||
\n
|
||||
\n请确保先安装 .fw 文件,再安装 .res 文件。您的手环将会在安装了 .fw 文件后重启
|
||||
\n
|
||||
\n备注:如果您安装的 .res 文件和之前相同,则无需安装 .res 文件
|
||||
\n
|
||||
\n风险自担!</string>
|
||||
<string name="devicetype_amazfit_gtr">华米 GTR</string>
|
||||
<string name="fw_upgrade_notice_amazfitgtr">即将在您的 华米 GTR (Amazfit GTR) 上安装固件 %s 。
|
||||
\n
|
||||
\n请确保先安装 .fw 文件,然后再安装 .res 文件,最后再安装 .gps 文件。您的手表将会安装了 .fw 文件后重启。
|
||||
\n
|
||||
\n注意:如果 .res 和 .gps 文件和上一个版本相同,您则无需安装。
|
||||
\n
|
||||
<string name="fw_upgrade_notice_amazfitgtr">即将在您的华米 GTR (Amazfit GTR) 上安装固件 %s 。
|
||||
\n
|
||||
\n请确保先安装 .fw 文件,然后再安装 .res 文件,最后再安装 .gps 文件。您的手表将会安装了 .fw 文件后重启。
|
||||
\n
|
||||
\n注意:如果 .res 和 .gps 文件和上一个版本相同,您则无需安装。
|
||||
\n
|
||||
\n风险自担!</string>
|
||||
<string name="pref_chart_heartrate_color_red">红</string>
|
||||
<string name="pref_chart_heartrate_color_orange">橙</string>
|
||||
@ -784,13 +784,13 @@
|
||||
<string name="pref_title_chart_sleep_rolling_24_hour">睡眠范围</string>
|
||||
<string name="pref_chart_sleep_rolling_24_on">过去 24 小时</string>
|
||||
<string name="pref_chart_sleep_rolling_24_off">中午到中午</string>
|
||||
<string name="devicetype_amazfit_gts">米动 GTS</string>
|
||||
<string name="fw_upgrade_notice_amazfitgts">您即将在 米动手表GTS(Amazfit GTS)上安装 %s 版本的固件
|
||||
\n
|
||||
\n请确保先安装 .fw 文件,再安装 .res 文件。您的手环将会在安装了 .fw 文件后重启。
|
||||
\n
|
||||
\n备注:如果您安装的 .res 文件和之前相同,则无需安装 .res 文件。
|
||||
\n
|
||||
<string name="devicetype_amazfit_gts">华米 GTS</string>
|
||||
<string name="fw_upgrade_notice_amazfitgts">您即将在华米手表 GTS(Amazfit GTS)上安装 %s 版本的固件
|
||||
\n
|
||||
\n请确保先安装 .fw 文件,再安装 .res 文件。您的手环将会在安装了 .fw 文件后重启。
|
||||
\n
|
||||
\n备注:如果您安装的 .res 文件和之前相同,则无需安装 .res 文件。
|
||||
\n
|
||||
\n风险自担!</string>
|
||||
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
|
||||
<string name="devicetype_qhybrid">Fossil Q Hybrid</string>
|
||||
@ -847,4 +847,10 @@
|
||||
<string name="pref_title_upper_button_function">上按钮</string>
|
||||
<string name="pref_title_middle_button_function">中按钮</string>
|
||||
<string name="pref_title_lower_button_function">下按钮</string>
|
||||
<string name="pref_title_vibration_strength">振动强度</string>
|
||||
<string name="devicetype_amazfit_bips">华米手表青春版 S</string>
|
||||
<string name="pref_title_relax_firmware_checks">若您希望刷入并非为您设备设计的固件,请选中此项(风险自担)</string>
|
||||
<string name="pref_summary_relax_firmware_checks">放宽固件检查</string>
|
||||
<string name="pref_header_auto_fetch">自动获取</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">绘制小部件圆圈</string>
|
||||
</resources>
|
@ -372,7 +372,7 @@
|
||||
<string name="appmanager_weather_install_provider">安裝天氣通知應用程式</string>
|
||||
<string name="app_move_to_top">移到最上方</string>
|
||||
<string name="pref_title_notifications_repetitions">重複次數</string>
|
||||
<string name="pref_summary_expose_hr">允許其他應用程式在裝置已連線時存取及時心率資料</string>
|
||||
<string name="pref_summary_expose_hr">允許其他應用程式在裝置已連線時存取即時心率資料</string>
|
||||
<string name="activity_prefs_alarm_max_heart_rate">最高心率</string>
|
||||
<string name="zetime_prefs_inactivity_repetitions">重複次數</string>
|
||||
<string name="appinstaller_install">安裝</string>
|
||||
@ -468,4 +468,77 @@
|
||||
<string name="hr_widget_weather">天氣</string>
|
||||
<string name="find_lost_device_you_found_it">找到了!</string>
|
||||
<string name="find_my_phone_notification">尋找我的手機</string>
|
||||
<string name="devicetype_amazfit_bips">華米 Bip S</string>
|
||||
<string name="hr_widget_nothing">沒有</string>
|
||||
<string name="hr_widget_calories">卡路里</string>
|
||||
<string name="error_no_location_access">位置存取權限必須被授予並啟用才能進行掃描</string>
|
||||
<string name="devicetype_y5">Y5</string>
|
||||
<string name="devicetype_banglejs">Bangle.js</string>
|
||||
<string name="qhybrid_goal_in_steps">目標步數</string>
|
||||
<string name="qhybrid_vibration_strength">振動強度:</string>
|
||||
<string name="save_configuration">儲存設定</string>
|
||||
<string name="toast_app_must_not_be_blacklisted">應用程式必須不在黑名單內才能設定</string>
|
||||
<string name="preferences_fm_frequency">FM 頻率</string>
|
||||
<string name="preferences_led_color">LED 顏色</string>
|
||||
<string name="no_data">沒有資料</string>
|
||||
<string name="watch9_time_seconds">秒:</string>
|
||||
<string name="watch9_time_hours">小時:</string>
|
||||
<string name="watch9_time_minutes">分鐘:</string>
|
||||
<string name="menuitem_compass">羅盤</string>
|
||||
<string name="notification_channel_name">Gadgetbridge 通知</string>
|
||||
<string name="devicetype_roidmi3">睿米3</string>
|
||||
<string name="devicetype_roidmi">睿米</string>
|
||||
<string name="devicetype_watch9">Watch 9</string>
|
||||
<string name="devicetype_mykronoz_zetime">MyKronoz ZeTime</string>
|
||||
<string name="devicetype_no1_f1">No.1 F1</string>
|
||||
<string name="devicetype_amazfit_bip">華米 Bip</string>
|
||||
<string name="kind_invalid">無效的資料</string>
|
||||
<string name="activity_type_walking">步行</string>
|
||||
<string name="activity_type_running">跑步</string>
|
||||
<string name="discovery_dont_pair">不配對</string>
|
||||
<string name="discovery_pair_title">與%1$s進行配對\?</string>
|
||||
<string name="discovery_attempting_to_pair">正在嘗試與%1$s進行配對</string>
|
||||
<string name="mi2_enable_text_notifications">文字通知</string>
|
||||
<string name="ok">好</string>
|
||||
<string name="activity_DB_delete_legacy_button">刪除舊的資料庫</string>
|
||||
<string name="dbmanagementactivity_import_successful">已匯入。</string>
|
||||
<string name="dbmanagementactivity_exported_to">已匯出到:%1$s</string>
|
||||
<string name="updatefirmwareoperation_firmware_not_sent">韌體未傳送</string>
|
||||
<string name="device_fw">韌體版本:%1$s</string>
|
||||
<string name="authenticating">驗證中</string>
|
||||
<string name="fwinstaller_firmware_not_compatible_to_device">此韌體與該裝置不相容</string>
|
||||
<string name="miband_fwinstaller_incompatible_version">不相容的版本</string>
|
||||
<string name="updatefirmwareoperation_write_failed">韌體安裝失敗</string>
|
||||
<string name="updatefirmwareoperation_updateproblem_do_not_reboot">在傳輸韌體時發生問題。請勿重啟您的小米手環!</string>
|
||||
<string name="fwapp_install_device_not_ready">檔案無法被安裝,裝置未就緒。</string>
|
||||
<string name="chart_no_data_synchronize">尚無資料。同步裝置?</string>
|
||||
<string name="pref_screen_notification_profile_calendar">日曆通知</string>
|
||||
<string name="discovery_need_to_enter_authkey">此裝置需要一組驗證密鑰,在裝置上長按以進入設定。詳細資訊請閱讀專案 wiki。</string>
|
||||
<string name="miband_pairing_tap_hint">當您的小米手環振動並閃爍時,請連續點擊數次。</string>
|
||||
<string name="pairing_already_bonded">已與裝置 %1$s (%2$s) 完成綁定,連線中…</string>
|
||||
<string name="title_activity_mi_band_pairing">配對您的小米手環</string>
|
||||
<string name="title_activity_android_pairing">配對裝置</string>
|
||||
<string name="initialized">初始化完成</string>
|
||||
<string name="gadgetbridge_running">Gadgetbridge 正在執行</string>
|
||||
<string name="tap_a_device_to_connect">點擊一個裝置以進行連線</string>
|
||||
<string name="bluetooth_is_not_supported_">藍芽不支援。</string>
|
||||
<string name="zetime_calories_type_all">涵蓋活動與未活動時消耗的卡路里</string>
|
||||
<string name="zetime_calories_type_active">僅活動時消耗的卡路里</string>
|
||||
<string name="zetime_calories_type">卡路里種類</string>
|
||||
<string name="zetime_activity_tracking_summary">開啟活動追蹤將紀錄您的步數等資料。</string>
|
||||
<string name="zetime_activity_tracking">活動追蹤</string>
|
||||
<string name="zetime_heart_rate_alarm_enable">啟用心率警告</string>
|
||||
<string name="zetime_title_heart_rate_alarm_summary">手錶將會在您的心率超過限制時警告您。</string>
|
||||
<string name="zetime_title_heart_rate_alarm">心率警告</string>
|
||||
<string name="pref_summary_use_custom_font">若您的裝置使用了自訂的字體以支援表情符號,請開啟此功能</string>
|
||||
<string name="pref_title_use_custom_font">使用自訂字體</string>
|
||||
<string name="pref_title_pebble_reconnect_attempts">重新連線嘗試次數</string>
|
||||
<string name="pref_title_pebble_forceuntested">啟用尚未測試的功能</string>
|
||||
<string name="pref_title_location_keep_uptodate">保持位置持續更新</string>
|
||||
<string name="pref_title_location_latitude">緯度</string>
|
||||
<string name="pref_title_location_aquire">取得位置</string>
|
||||
<string name="pref_header_location">位置</string>
|
||||
<string name="pref_title_enable_pebblekit">允許第三方 Android 應用程式存取</string>
|
||||
<string name="pref_title_enable_outgoing_call">支援撥出電話</string>
|
||||
<string name="title_activity_calblacklist">列入黑名單的日曆</string>
|
||||
</resources>
|
@ -186,6 +186,8 @@
|
||||
<string name="pref_summary_allow_high_mtu">Increases transfer speed, but might not work on some Android devices.</string>
|
||||
<string name="pref_summary_sync_calendar">Enables calendar alerts, even when disconnected</string>
|
||||
<string name="pref_title_sync_caldendar">Sync calendar events</string>
|
||||
<string name="pref_summary_relax_firmware_checks">Relax firmware checks</string>
|
||||
<string name="pref_title_relax_firmware_checks">Enable this if you want to flash a firmware not intended for you device (at your own risk)</string>
|
||||
<string name="pref_title_vibration_strength">Vibration strength</string>
|
||||
<string name="pref_display_add_device_fab">Connect new device button</string>
|
||||
<string name="pref_display_add_device_fab_on">Always visible</string>
|
||||
@ -293,6 +295,7 @@
|
||||
<string name="pref_title_auto_export_interval">Export interval</string>
|
||||
<string name="pref_summary_auto_export_interval">Export every %d hour</string>
|
||||
<!-- Auto fetch activity preferences -->
|
||||
<string name="pref_header_auto_fetch">Auto fetch</string>
|
||||
<string name="pref_auto_fetch">Auto fetch activity data</string>
|
||||
<string name="pref_auto_fetch_summary">Fetch happens upon screen unlock. Only works if a lock mechanism is set!</string>
|
||||
<string name="pref_auto_fetch_limit_fetches">Minimum time between fetches</string>
|
||||
@ -717,6 +720,7 @@
|
||||
<string name="devicetype_amazfit_cor">Amazfit Cor</string>
|
||||
<string name="devicetype_amazfit_cor2">Amazfit Cor 2</string>
|
||||
<string name="devicetype_amazfit_gtr">Amazfit GTR</string>
|
||||
<string name="devicetype_amazfit_bips">Amazfit Bip S</string>
|
||||
<string name="devicetype_vibratissimo">Vibratissimo</string>
|
||||
<string name="devicetype_liveview">LiveView</string>
|
||||
<string name="devicetype_hplus">HPlus</string>
|
||||
@ -851,6 +855,7 @@
|
||||
<string name="prefs_button_long_press_action_selection_title">Long press button action</string>
|
||||
|
||||
<string name="error_no_location_access">Location access must be granted and enabled for scanning to work properly</string>
|
||||
<string name="pref_qhybrid_title_widget_draw_circles">Draw widget circles</string>
|
||||
|
||||
<plurals name="widget_alarm_target_hours">
|
||||
<item quantity="one">%d hour</item>
|
||||
|
@ -1,5 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<changelog>
|
||||
<release version="0.43.2" versioncode="171">
|
||||
<change>Fossil Hybrid HR: Allow choosing and cropping image to be set as watch background</change>
|
||||
<change>Fossil Hybrid HR: Option to draw circles around widgets</change>
|
||||
<change>Fossil Hybrid HR: Experimenal firmware update support</change>
|
||||
<change>Fossil Hybrid HR: Fix vibration strength setting</change>
|
||||
<change>Huami: Do not display firmware information and whitelist information when flashing watchfaces</change>
|
||||
<change>Huami: Disable air quality indicator on Huami devices instead of showing 0</change>
|
||||
<change>Bangle.js: Change encoded char set to match Espruino's 8 bit fonts</change>
|
||||
<change>Steps/Sleep averages: Skip days with zero data</change>
|
||||
</release>
|
||||
<release version="0.43.1" versioncode="170">
|
||||
<change>Initial support for Amazfit Bip S (incomplete, needs the official app once to obtain the pairing key)</change>
|
||||
<change>Amazift Bip Lite: Allow relaxing firmware checks to allow flashing of the regular Bip firmware (for the brave)</change>
|
||||
<change>Fossil Hybrid HR: Fix notification history on newer firmwares</change>
|
||||
<change>Fossil Hybrid HR: Add option to disable widget circle</change>
|
||||
<change>Bangle.js: Don't set time if the option is turned off in settings</change>
|
||||
<change>Bangle.js: DST and time zone fixes</change>
|
||||
<change>Add Arabic-style Eastern Arabic numerals to transliteration</change>
|
||||
</release>
|
||||
<release version="0.43.0" versioncode="169">
|
||||
<change>Initial support for Fossil Hybrid HR (needs complicated key extraction, read wiki)</change>
|
||||
<change>Fossil: Allow switching off the Q Icon and use the default Gadgetbridge icon</change>
|
||||
|
@ -27,9 +27,14 @@
|
||||
android:key="force_white_color_scheme"
|
||||
android:summary="@string/pref_summary_force_white_color_scheme"
|
||||
android:title="@string/pref_title_force_white_color_scheme" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="widget_draw_circles"
|
||||
android:title="@string/pref_qhybrid_title_widget_draw_circles" />
|
||||
|
||||
<SeekBarPreference
|
||||
android:defaultValue="2"
|
||||
android:key="@string/pref_title_vibration_strength"
|
||||
android:key="vibration_strength"
|
||||
android:max="3"
|
||||
android:title="@string/pref_title_vibration_strength"
|
||||
app:showSeekBarValue="true" />
|
||||
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="relax_firmware_checks"
|
||||
android:summary="@string/pref_summary_relax_firmware_checks"
|
||||
android:title="@string/pref_title_relax_firmware_checks" />
|
||||
</androidx.preference.PreferenceScreen>
|
@ -609,7 +609,7 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="Auto fetch">
|
||||
android:title="@string/pref_header_auto_fetch">
|
||||
<CheckBoxPreference
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:defaultValue="false"
|
||||
|
@ -6,6 +6,7 @@ import org.junit.Test;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.KoreanLanguageUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@ -39,7 +40,7 @@ public class LanguageUtilsTest extends TestBase {
|
||||
String pangram = "نص حكيم له سر قاطع وذو شأن عظيم مكتوب على ثوب أخضر ومغلف بجلد أزرق";
|
||||
String pangramExpected = "n9 7kym lh sr qa63 wthw sh2n 36'ym mktwb 3la thwb 259'r wm3'lf bjld 2zrq";
|
||||
String pangramActual = LanguageUtils.transliterate(pangram);
|
||||
assertEquals("pangram transliteration failed", pangramExpected, pangramActual);
|
||||
assertEquals("Arabic pangram transliteration failed", pangramExpected, pangramActual);
|
||||
|
||||
String taMarbutah = "ﺓ";
|
||||
String taMarbutahExpected = "";
|
||||
@ -51,6 +52,14 @@ public class LanguageUtilsTest extends TestBase {
|
||||
String hamzaActual = LanguageUtils.transliterate(hamza);
|
||||
assertEquals("hamza transliteration failed", hamzaExpected, hamzaActual);
|
||||
|
||||
String easternArabicNumeralsArabic = "٠١٢٣٤٥٦٧٨٩";
|
||||
String easternArabicNumeralsFarsi = "۰۱۲۳۴۵۶۷۸۹";
|
||||
String easternArabicNumeralsExpected = "0123456789";
|
||||
assertEquals("Eastern Arabic numerals (Arabic) failed", easternArabicNumeralsExpected,
|
||||
LanguageUtils.transliterate(easternArabicNumeralsArabic));
|
||||
assertEquals("Eastern Arabic numerals (Farsi) failed", easternArabicNumeralsExpected,
|
||||
LanguageUtils.transliterate(easternArabicNumeralsFarsi));
|
||||
|
||||
String farsi = "گچپژ";
|
||||
String farsiExpected = "gchpzh";
|
||||
String farsiActual = LanguageUtils.transliterate(farsi);
|
||||
@ -74,6 +83,43 @@ public class LanguageUtilsTest extends TestBase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringTransliterateKorean() {
|
||||
// A familiar phrase with no special provisions.
|
||||
String hello = "안녕하세요";
|
||||
String helloExpected = "annyeonghaseyo";
|
||||
String helloActual = LanguageUtils.transliterate(hello);
|
||||
assertEquals("Korean hello transliteration failed", helloExpected, helloActual);
|
||||
|
||||
// Korean pangram. Includes some ASCII punctuation which should not be changed by
|
||||
// transliteration.
|
||||
//
|
||||
// Translation: "Chocolate!? What I wanted was some rice puffs and clothes." "Child, why are
|
||||
// you complaining again?"
|
||||
String pangram = "\"웬 초콜릿? 제가 원했던 건 뻥튀기 쬐끔과 의류예요.\" \"얘야, 왜 또 불평?\"";
|
||||
String pangramExpected = "\"wen chokollit? jega wonhaetdeon geon ppeongtwigi jjoekkeumgwa uiryuyeyo.\" \"yaeya, wae tto bulpyeong?\"";
|
||||
String pangramActual = LanguageUtils.transliterate(pangram);
|
||||
assertEquals("Korean pangram transliteration failed", pangramExpected, pangramActual);
|
||||
|
||||
// Several words excercising special provisions, from Wikipedia.
|
||||
String special = "좋고, 놓다, 잡혀, 낳지";
|
||||
String specialExpected = "joko, nota, japhyeo, nachi";
|
||||
String specialActual = LanguageUtils.transliterate(special);
|
||||
assertEquals("Korean special provisions transliteration failed", specialExpected, specialActual);
|
||||
|
||||
// Isolated jamo.
|
||||
String isolatedJamo = "ㅋㅋㅋ";
|
||||
String isolatedJamoExpected = "kkk";
|
||||
String isolatedJamoActual = LanguageUtils.transliterate(isolatedJamo);
|
||||
assertEquals("Korean isolated jamo transliteration failed", isolatedJamoExpected, isolatedJamoActual);
|
||||
|
||||
// Korean transliteration shouldn't touch non-Hangul composites.
|
||||
String german = "schön";
|
||||
String germanExpected = german;
|
||||
String germanActual = KoreanLanguageUtils.transliterate(german);
|
||||
assertEquals("Korean transliteration modified a non-Hangul composite", germanExpected, germanActual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringTransliterateLithuanian() {
|
||||
String input = "ą č ę ė į š ų ū ž";
|
||||
|
@ -9,7 +9,7 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.1'
|
||||
classpath 'com.android.tools.build:gradle:3.6.2'
|
||||
classpath "gradle.plugin.com.github.spotbugs:spotbugs-gradle-plugin:2.0.0"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
7
fastlane/metadata/android/en-US/changelogs/170.txt
Normal file
7
fastlane/metadata/android/en-US/changelogs/170.txt
Normal file
@ -0,0 +1,7 @@
|
||||
* Initial support for Amazfit Bip S (incomplete, needs the official app once to obtain the pairing key)
|
||||
* Amazift Bip Lite: Allow relaxing firmware checks to allow flashing of the regular Bip firmware (for the brave)
|
||||
* Fossil Hybrid HR: Fix notification history on newer firmwares
|
||||
* Fossil Hybrid HR: Add option to disable widget circle
|
||||
* Bangle.js: Don't set time if the option is turned off in settings
|
||||
* Bangle.js: DST and time zone fixes
|
||||
* Add Arabic-style Eastern Arabic numerals to transliteration
|
8
fastlane/metadata/android/en-US/changelogs/171.txt
Normal file
8
fastlane/metadata/android/en-US/changelogs/171.txt
Normal file
@ -0,0 +1,8 @@
|
||||
* Fossil Hybrid HR: Allow choosing and cropping image to be set as watch background
|
||||
* Fossil Hybrid HR: Option to draw circles around widgets
|
||||
* Fossil Hybrid HR: Experimenal firmware update support
|
||||
* Fossil Hybrid HR: Fix vibration strength setting
|
||||
* Huami: Do not display firmware information and whitelist information when flashing watchfaces
|
||||
* Huami: Disable air quality indicator on Huami devices instead of showing 0
|
||||
* Bangle.js: Change encoded char set to match Espruino's 8 bit fonts
|
||||
* Steps/Sleep averages: Skip days with zero data
|
Loading…
Reference in New Issue
Block a user