1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-07-24 15:43:46 +02:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Vadim Kaushan 2018-07-29 19:31:40 +03:00
commit 458a363f11
40 changed files with 451 additions and 55 deletions

View File

@ -1,5 +1,21 @@
### Changelog
#### Version 0.28.1
* Fix wrong weather icon mapping in rare cases
* Fix device discovery on Android 4.4
* Amazfit Bip: Use UTC in gpx tracks for better compatibility with external software
* Amazfit Bip: Add the (localized) activity type to the gpx filename
* Amazfit Bip: Fix weather on latest firmwares
#### Version 0.28.0
* Initial support for ZeTime
* Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme
* Amazfit Bip: Support setting language to Russian
* Amazfit Cor: Support language switching on newer firmwares
* Mi Band 3: support setting language (english and spanish tested)
* Mi Band 3: Fix pairing
* Mi Band 3: Send AQI to enable display of current temperature
#### Version 0.27.1
* Pebble: Change appstore search to point to RomanPort's pebble appstore
* Mi Band 3: Allow flashing fonts (untested)

View File

@ -2,7 +2,7 @@ Gadgetbridge
============
Gadgetbridge is an Android (4.4+) application which will allow you to use your
Pebble, Mi Band, Amazfit Bit and HPlus device (and more) without the vendor's closed source application
Pebble, Mi Band, Amazfit Bip and HPlus device (and more) without the vendor's closed source application
and without the need to create an account and transmit any of your data to the
vendor's servers.
@ -26,11 +26,13 @@ vendor's servers.
* Pebble 2 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble)
* Mi Band, Mi Band 1A, Mi Band 1S [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band)
* Mi Band 2 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2)
* Mi Band 3 [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-3)
* Amazfit Bip [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip)
* Amazfit Cor (no maintainer) [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor)
* HPlus Devices (e.g. ZeBand) [Wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki/HPlus)
* Teclast H10, H30 (WIP)
* NO.1 F1 (WIP)
* ZeTime (WIP)
* Liveview
* Vibratissimo (experimental)
* XWatch (Affordable Chinese Casio-like smartwatches)
@ -92,6 +94,8 @@ For more information read [this wiki article](https://github.com/Freeyourgadget/
* João Paulo Barraca (HPlus)
* Vitaly Svyastyn (NO.1 F1)
* Sami Alaoui (Teclast H30)
* "ladbsoft" (XWatch)
* Sebastian Kranz (ZeTime)
## Contribute

View File

@ -25,8 +25,8 @@ android {
targetSdkVersion 27
// Note: always bump BOTH versionCode and versionName!
versionName "0.27.1"
versionCode 133
versionName "0.28.1"
versionCode 135
vectorDrawables.useSupportLibrary = true
}
buildTypes {

View File

@ -231,9 +231,7 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
public void logMessageContent(byte[] value) {
if (value != null) {
for (byte b : value) {
LOG.warn("DATA: " + String.format("0x%2x", b) + " - " + (char) (b & 0xff));
}
LOG.warn("DATA: " + GB.hexdump(value, 0, value.length));
}
}
@ -630,7 +628,7 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
super.onPause();
stopBTDiscovery();
stopBTLEDiscovery();
if (GB.supportsBluetoothLE()) {
if (GBApplication.isRunningLollipopOrLater()) {
stopNewBTLEDiscovery();
}
}

View File

@ -249,7 +249,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
);
holder.findDevice.setVisibility(device.isInitialized() ? View.VISIBLE : View.GONE);
holder.findDevice.setVisibility(device.isInitialized() && coordinator.supportsFindDevice() ? View.VISIBLE : View.GONE);
holder.findDevice.setOnClickListener(new View.OnClickListener()
{

View File

@ -242,4 +242,10 @@ public interface DeviceCoordinator {
* forecast display.
*/
boolean supportsWeather();
/**
* Indicates whether the device supports being found by vibrating,
* making some sound or lighting up
*/
boolean supportsFindDevice();
}

View File

@ -181,4 +181,9 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
public boolean supportsWeather() {
return false;
}
@Override
public boolean supportsFindDevice() {
return false;
}
}

View File

@ -103,6 +103,11 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
return false;
}
@Override
public boolean supportsFindDevice() {
return true;
}
@Override
public DeviceType getDeviceType() {
return DeviceType.HPLUS;

View File

@ -263,4 +263,9 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator {
public boolean supportsSmartWakeup(GBDevice device) {
return false;
}
@Override
public boolean supportsFindDevice() {
return true;
}
}

View File

@ -89,6 +89,11 @@ public class TeclastH30Coordinator extends AbstractDeviceCoordinator {
return false;
}
@Override
public boolean supportsFindDevice() {
return true;
}
@Override
public DeviceType getDeviceType() {
return DeviceType.TECLASTH30;

View File

@ -124,6 +124,11 @@ public class LiveviewCoordinator extends AbstractDeviceCoordinator {
return false;
}
@Override
public boolean supportsFindDevice() {
return true;
}
@Override
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
// nothing to delete, yet

View File

@ -50,6 +50,8 @@ public class MiBand2Service {
public static final UUID UUID_CHARACTERISTIC_AUTH = UUID.fromString("00000009-0000-3512-2118-0009af100700");
public static final UUID UUID_CHARACTERISTIC_DEVICEEVENT = UUID.fromString("00000010-0000-3512-2118-0009af100700");
public static final UUID UUID_CHARACTERISTIC_CHUNKEDTRANSFER = UUID.fromString("00000020-0000-3512-2118-0009af100700");
public static final int ALERT_LEVEL_NONE = 0;
public static final int ALERT_LEVEL_MESSAGE = 1;
public static final int ALERT_LEVEL_PHONE_CALL = 2;
@ -101,7 +103,7 @@ public class MiBand2Service {
/**
* In some logs it's 0x0...
*/
public static final byte AUTH_BYTE = 0x8;
public static final byte AUTH_BYTE = 0x08;
// maybe not really activity data, but steps?
public static final byte COMMAND_FETCH_DATA = 0x02;

View File

@ -176,6 +176,11 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator {
return false;
}
@Override
public boolean supportsFindDevice() {
return true;
}
public static boolean hasValidUserInfo() {
String dummyMacAddress = MiBandService.MAC_ADDRESS_FILTER_1_1A + ":00:00:00";
try {

View File

@ -152,6 +152,11 @@ public class No1F1Coordinator extends AbstractDeviceCoordinator {
return false;
}
@Override
public boolean supportsFindDevice() {
return true;
}
@Override
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
Long deviceId = device.getId();

View File

@ -160,4 +160,9 @@ public class PebbleCoordinator extends AbstractDeviceCoordinator {
public boolean supportsWeather() {
return true;
}
@Override
public boolean supportsFindDevice() {
return true;
}
}

View File

@ -125,6 +125,11 @@ public class VibratissimoCoordinator extends AbstractDeviceCoordinator {
return false;
}
@Override
public boolean supportsFindDevice() {
return true;
}
@Override
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
// nothing to delete, yet

View File

@ -130,4 +130,9 @@ public class XWatchCoordinator extends AbstractDeviceCoordinator {
public boolean supportsWeather() {
return false;
}
@Override
public boolean supportsFindDevice() {
return true;
}
}

View File

@ -67,6 +67,11 @@ public class ZeTimeCoordinator extends AbstractDeviceCoordinator {
return true;
}
@Override
public boolean supportsFindDevice() {
return true;
}
@Override
public InstallHandler findInstallHandler(Uri uri, Context context) {
return null;

View File

@ -131,7 +131,7 @@ public class GPXExporter implements ActivityTrackExporter {
ser.attribute(NS_DEFAULT, "lon", formatLocation(location.getLongitude()));
ser.attribute(NS_DEFAULT, "lat", formatLocation(location.getLatitude()));
ser.startTag(NS_DEFAULT, "ele").text(formatLocation(location.getAltitude())).endTag(NS_DEFAULT, "ele");
ser.startTag(NS_DEFAULT, "time").text(formatTime(point.getTime())).endTag(NS_DEFAULT, "time");
ser.startTag(NS_DEFAULT, "time").text(DateTimeUtils.formatIso8601UTC(point.getTime())).endTag(NS_DEFAULT, "time");
String description = point.getDescription();
if (description != null) {
ser.startTag(NS_DEFAULT, "desc").text(description).endTag(NS_DEFAULT, "desc");

View File

@ -142,7 +142,8 @@ public class GBDeviceService implements DeviceService {
.putExtra(EXTRA_NOTIFICATION_ID, notificationSpec.id)
.putExtra(EXTRA_NOTIFICATION_TYPE, notificationSpec.type)
.putExtra(EXTRA_NOTIFICATION_SOURCENAME, notificationSpec.sourceName)
.putExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR, notificationSpec.pebbleColor);
.putExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR, notificationSpec.pebbleColor)
.putExtra(EXTRA_NOTIFICATION_SOURCEAPPID, notificationSpec.sourceAppId);
invokeService(intent);
}

View File

@ -71,6 +71,7 @@ public interface DeviceService extends EventHandler {
String EXTRA_NOTIFICATION_PHONENUMBER = "notification_phonenumber";
String EXTRA_NOTIFICATION_SENDER = "notification_sender";
String EXTRA_NOTIFICATION_SOURCENAME = "notification_sourcename";
String EXTRA_NOTIFICATION_SOURCEAPPID = "notification_sourceappid";
String EXTRA_NOTIFICATION_SUBJECT = "notification_subject";
String EXTRA_NOTIFICATION_TITLE = "notification_title";
String EXTRA_NOTIFICATION_TYPE = "notification_type";

View File

@ -433,7 +433,7 @@ public class Weather {
return 801;
case 45: //thundershowers
case 47: //isolated thundershowers
return 621;
return 211;
case 3200: //not available
default:
return -1;

View File

@ -148,6 +148,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOT
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_PEBBLE_COLOR;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_PHONENUMBER;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SENDER;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SOURCEAPPID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SOURCENAME;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SUBJECT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TITLE;
@ -348,6 +349,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
notificationSpec.pebbleColor = (byte) intent.getSerializableExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR);
notificationSpec.id = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
notificationSpec.flags = intent.getIntExtra(EXTRA_NOTIFICATION_FLAGS, 0);
notificationSpec.sourceAppId = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCEAPPID);
if (notificationSpec.type == NotificationType.GENERIC_SMS && notificationSpec.phoneNumber != null) {
notificationSpec.id = mRandom.nextInt(); // FIXME: add this in external SMS Receiver?

View File

@ -153,7 +153,8 @@ public class DeviceSupportFactory {
break;
case XWATCH:
deviceSupport = new ServiceDeviceSupport(new XWatchSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
case ZETIME:
break;
case ZETIME:
deviceSupport = new ServiceDeviceSupport(new ZeTimeDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
break;
case ID115:

View File

@ -50,12 +50,12 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWrit
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.operations.AmazfitBipFetchLogsOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiIcon;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.operations.AmazfitBipFetchLogsOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.MiBand2Support;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchActivityOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchSportsSummaryOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Version;
@ -247,7 +247,7 @@ public class AmazfitBipSupport extends MiBand2Support {
LOG.error("Error sending current weather", ex);
}
if (gbDevice.getType() == DeviceType.AMAZFITBIP) {
if (gbDevice.getType() != DeviceType.AMAZFITCOR) {
try {
TransactionBuilder builder;
builder = performInitialized("Sending air quality index");
@ -310,7 +310,6 @@ public class AmazfitBipSupport extends MiBand2Support {
for (WeatherSpec.Forecast forecast : weatherSpec.forecasts) {
condition = HuamiWeatherConditions.mapToAmazfitBipWeatherCode(forecast.conditionCode);
buf.put(condition);
buf.put(condition);
buf.put((byte) (forecast.maxTemp - 273));
@ -321,7 +320,12 @@ public class AmazfitBipSupport extends MiBand2Support {
}
}
builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array());
if (characteristicChunked != null) {
writeToChunked(builder, 1, buf.array());
} else {
builder.write(getCharacteristic(AmazfitBipService.UUID_CHARACTERISTIC_WEATHER), buf.array());
}
builder.queue(getQueue());
} catch (Exception ex) {
LOG.error("Error sending weather forecast", ex);
@ -427,6 +431,10 @@ public class AmazfitBipSupport extends MiBand2Support {
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SPANISH;
localeString = "es_ES";
break;
case 4:
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
localeString = "ru_RU";
break;
default:
switch (language) {
case "zh":
@ -442,6 +450,10 @@ public class AmazfitBipSupport extends MiBand2Support {
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SPANISH;
localeString = "es_ES";
break;
case "ru":
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
localeString = "ru_RU";
break;
default:
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
localeString = "en_US";
@ -454,7 +466,9 @@ public class AmazfitBipSupport extends MiBand2Support {
builder.add(new ConditionalWriteAction(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION)) {
@Override
protected byte[] checkCondition() {
if (gbDevice.getType() == DeviceType.MIBAND3 || (gbDevice.getType() == DeviceType.AMAZFITBIP && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("0.1.0.77")) >= 0)) {
if (gbDevice.getType() == DeviceType.MIBAND3 ||
(gbDevice.getType() == DeviceType.AMAZFITBIP && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("0.1.0.77")) >= 0) ||
(gbDevice.getType() == DeviceType.AMAZFITCOR && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("1.0.7.23")) >= 0)) {
return command_new;
} else {
return command_old;

View File

@ -57,6 +57,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.ActivateDisplayOnLift;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService;
@ -69,7 +70,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
@ -84,6 +84,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CalendarEvents;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@ -103,13 +104,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.Hear
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.RealtimeSamplesSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.actions.StopNotificationAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchActivityOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.FetchSportsSummaryOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.InitOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.operations.UpdateFirmwareOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.RealtimeSamplesSupport;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
@ -155,7 +156,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
}
};
BluetoothGattCharacteristic characteristicHRControlPoint;
private BluetoothGattCharacteristic characteristicHRControlPoint;
protected BluetoothGattCharacteristic characteristicChunked;
private boolean needsAuth;
private volatile boolean telephoneRinging;
@ -209,8 +211,13 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
try {
boolean authenticate = needsAuth;
needsAuth = false;
new InitOperation(authenticate, this, builder).perform();
byte authFlags = MiBand2Service.AUTH_BYTE;
if (gbDevice.getType() == DeviceType.MIBAND3) {
authFlags = 0x00;
}
new InitOperation(authenticate, authFlags, this, builder).perform();
characteristicHRControlPoint = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT);
characteristicChunked = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_CHUNKEDTRANSFER);
} catch (IOException e) {
GB.toast(getContext(), "Initializing Mi Band 2 failed", Toast.LENGTH_SHORT, GB.ERROR, e);
}
@ -1604,6 +1611,34 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
return this;
}
protected void writeToChunked(TransactionBuilder builder, int type, byte[] data) {
final int MAX_CHUNKLENGTH = 17;
int remaining = data.length;
byte count = 0;
while (remaining > 0) {
int copybytes = Math.min(remaining, MAX_CHUNKLENGTH);
byte[] chunk = new byte[copybytes + 3];
byte flags = 0;
if (remaining <= MAX_CHUNKLENGTH) {
flags |= 0x80; // last chunk
if (count == 0) {
flags |= 0x40; // weird but true
}
} else if (count > 0) {
flags |= 0x40; // consecutive chunk
}
chunk[0] = 0;
chunk[1] = (byte) (flags | type);
chunk[2] = (byte) (count & 0xff);
System.arraycopy(data, count++ * MAX_CHUNKLENGTH, chunk, 3, copybytes);
builder.write(characteristicChunked, chunk);
remaining -= copybytes;
}
}
public void phase2Initialize(TransactionBuilder builder) {
LOG.info("phase2Initialize...");
requestBatteryInfo(builder);

View File

@ -30,12 +30,14 @@ import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.Logging;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2Service;
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
import nodomain.freeyourgadget.gadgetbridge.export.ActivityTrackExporter;
import nodomain.freeyourgadget.gadgetbridge.export.GPXExporter;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityTrack;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
@ -99,7 +101,22 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
try {
ActivityTrack track = parser.parse(buffer.toByteArray());
ActivityTrackExporter exporter = createExporter();
String fileName = FileUtils.makeValidFileName("gadgetbridge-track-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx");
String trackType = "track";
switch (summary.getActivityKind()) {
case ActivityKind.TYPE_CYCLING:
trackType = getContext().getString(R.string.activity_type_biking);
break;
case ActivityKind.TYPE_RUNNING:
trackType = getContext().getString(R.string.activity_type_running);
break;
case ActivityKind.TYPE_WALKING:
trackType = getContext().getString(R.string.activity_type_walking);
break;
case ActivityKind.TYPE_SWIMMING:
trackType = getContext().getString(R.string.activity_type_swimming);
break;
}
String fileName = FileUtils.makeValidFileName("gadgetbridge-"+trackType.toLowerCase()+"-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx");
File targetFile = new File(FileUtils.getExternalFilesDir(), fileName);
try {

View File

@ -49,10 +49,12 @@ public class InitOperation extends AbstractBTLEOperation<MiBand2Support> {
private final TransactionBuilder builder;
private final boolean needsAuth;
private final byte authFlags;
public InitOperation(boolean needsAuth, MiBand2Support support, TransactionBuilder builder) {
public InitOperation(boolean needsAuth, byte authFlags, MiBand2Support support, TransactionBuilder builder) {
super(support);
this.needsAuth = needsAuth;
this.authFlags = authFlags;
this.builder = builder;
builder.setGattCallback(this);
}
@ -63,7 +65,7 @@ public class InitOperation extends AbstractBTLEOperation<MiBand2Support> {
if (needsAuth) {
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.AUTHENTICATING, getContext()));
// write key to miband2
byte[] sendKey = org.apache.commons.lang3.ArrayUtils.addAll(new byte[]{MiBand2Service.AUTH_SEND_KEY, MiBand2Service.AUTH_BYTE}, getSecretKey());
byte[] sendKey = org.apache.commons.lang3.ArrayUtils.addAll(new byte[]{MiBand2Service.AUTH_SEND_KEY, authFlags}, getSecretKey());
builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_AUTH), sendKey);
} else {
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
@ -73,7 +75,7 @@ public class InitOperation extends AbstractBTLEOperation<MiBand2Support> {
}
private byte[] requestAuthNumber() {
return new byte[]{MiBand2Service.AUTH_REQUEST_RANDOM_AUTH_NUMBER, MiBand2Service.AUTH_BYTE};
return new byte[]{MiBand2Service.AUTH_REQUEST_RANDOM_AUTH_NUMBER, authFlags};
}
private byte[] getSecretKey() {
@ -105,7 +107,7 @@ public class InitOperation extends AbstractBTLEOperation<MiBand2Support> {
// md5??
byte[] eValue = handleAESAuth(value, getSecretKey());
byte[] responseValue = org.apache.commons.lang3.ArrayUtils.addAll(
new byte[]{MiBand2Service.AUTH_SEND_ENCRYPTED_AUTH_NUMBER, MiBand2Service.AUTH_BYTE}, eValue);
new byte[]{MiBand2Service.AUTH_SEND_ENCRYPTED_AUTH_NUMBER, authFlags}, eValue);
TransactionBuilder builder = createTransactionBuilder("Sending the encrypted random key to the band");
builder.write(characteristic, responseValue);

View File

@ -43,8 +43,13 @@ public class MiBand3FirmwareInfo extends HuamiFirmwareInfo {
static {
// firmware
crcToVersion.put(55852, "1.2.0.8");
// resources
crcToVersion.put(54724, "1.2.0.8");
// font
crcToVersion.put(19775, "1");
}
public MiBand3FirmwareInfo(byte[] bytes) {

View File

@ -51,7 +51,12 @@ public class DateTimeUtils {
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {
StringBuffer rfcFormat = super.format(date, toAppendTo, pos);
return rfcFormat.insert(rfcFormat.length() - 2, ":");
if (this.getTimeZone().equals(TimeZone.getTimeZone("UTC"))) {
rfcFormat.setLength(rfcFormat.length()-5);
return rfcFormat.append("Z");
} else {
return rfcFormat.insert(rfcFormat.length() - 2, ":");
}
}
}; //no public access, we have to workaround Android bugs
@ -64,6 +69,17 @@ public class DateTimeUtils {
if(GBApplication.isRunningNougatOrLater()){
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.US).format(date);
}
ISO_8601_FORMAT.setTimeZone(TimeZone.getDefault());
return ISO_8601_FORMAT.format(date);
}
public static String formatIso8601UTC(Date date) {
if(GBApplication.isRunningNougatOrLater()){
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf.format(date);
}
ISO_8601_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
return ISO_8601_FORMAT.format(date);
}

View File

@ -551,4 +551,8 @@
<string name="pref_auto_fetch_limit_fetches">זמן מזערי בין אחזורים</string>
<string name="pref_auto_fetch_limit_fetches_summary">מתבצע אחזור כל %s דקות</string>
<string name="devicetype_mykronoz_zetime">MyKronoz ZeTime</string>
<string name="russian">רוסית</string>
</resources>

View File

@ -388,7 +388,7 @@
<string name="pref_title_auto_export_interval">Intervalo de exportação</string>
<string name="pref_summary_auto_export_interval">Exportar a cada %d hora(s)</string>
<string name="preferences_amazfitbip_settings">Ajustes do Amazfit Bit</string>
<string name="preferences_amazfitbip_settings">Ajustes do Amazfit Bip</string>
<string name="discovery_connected_devices_hint">Permita que seu dispositivo seja detectado. Os dispositivos já pareados não serão detectados. Para o Android 6 ou superior, é necessário habilitar a localização de GPS. Desative o Privacy Guard para o Gadgetbridge, pois o telefone poderá travar ou reiniciar caso esteja ativo. Se nenhum dispositivo for encontrado após alguns minutos, tente novamente após reiniciar seu aparelho telefônico.</string>
<string name="prefs_title_heartrate_measurement_interval">Medição diária dos batimentos cardíacos</string>
<string name="interval_one_minute">A cada minuto</string>

View File

@ -0,0 +1,127 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources><string name="app_name">Gadgetbridge</string>
<string name="title_activity_controlcenter">Gadgetbridge</string>
<string name="action_settings">Setari</string>
<string name="action_debug">Depaneaza</string>
<string name="action_quit">Iesire</string>
<string name="action_donate">Doneaza</string>
<string name="controlcenter_fetch_activity_data">Sincronizeaza</string>
<string name="controlcenter_find_device">Gaseste bratara</string>
<string name="controlcenter_connect">Conecteaza</string>
<string name="controlcenter_disconnect">Deconecteaza</string>
<string name="controlcenter_delete_device">Sterge bratara</string>
<string name="controlcenter_delete_device_name">Sterge %1$s</string>
<string name="controlcenter_delete_device_dialogmessage">Va fi stearsa bratara si datele asociate!</string>
<string name="controlcenter_navigation_drawer_open">Deschide meniul de navigatie</string>
<string name="controlcenter_navigation_drawer_close">Inchide meniul de navigatie</string>
<string name="controlcenter_snackbar_need_longpress">Apasati lung pentru a deconecta</string>
<string name="title_activity_appmanager">Manager aplicatii</string>
<string name="appmananger_app_reinstall">Reinstaleaza</string>
<string name="appmanager_health_activate">Activeaza</string>
<string name="appmanager_health_deactivate">Dezactiveaza</string>
<string name="appmanager_hrm_activate">Activeaza Masurare ritm cardiac</string>
<string name="appmanager_hrm_deactivate">Dezactiveaza Masurare ritm cardiac</string>
<string name="appmanager_weather_activate">Activeaza Aplicatie meteo</string>
<string name="appmanager_weather_deactivate">Dezactiveaza Aplicatie meteo</string>
<string name="app_configure">Configureaza</string>
<string name="title_activity_appblacklist">Notificari blocate</string>
<string name="blacklist_all_for_notifications">Blocheaza toate notificarile</string>
<string name="whitelist_all_for_notifications">Permite toate notificarile</string>
<string name="title_activity_calblacklist">Calendare blocate</string>
<string name="title_activity_fw_app_insaller">Instalare firmware</string>
<string name="fw_multi_upgrade_notice">Esti pe punctul de a instala firmware-ul %1$s si %2$s, in locul celor deja instalate pe Mi Band.</string>
<string name="miband_firmware_known">Firmware-ul a fost testat si este compatibil cu Gadgetbridge.</string>
<string name="title_activity_settings">Setari</string>
<string name="pref_header_general">Setari generale</string>
<string name="pref_title_general_autoconnectonbluetooth">Conectare la bratara cand Bluetooth este pornit</string>
<string name="pref_title_general_autostartonboot">Porneste automat</string>
<string name="pref_title_general_autoreconnect">Reconecteare automata</string>
<string name="pref_default">Implicit</string>
<string name="pref_header_datetime">Data si Timp</string>
<string name="pref_title_datetime_syctimeonconnect">Sincronizare timp</string>
<string name="pref_title_theme">Tema</string>
<string name="pref_theme_light">Deschis</string>
<string name="pref_theme_dark">Intunecat</string>
<string name="pref_title_language">Limba</string>
<string name="pref_header_notifications">Notificari</string>
<string name="pref_title_notifications_call">Apeluri telefonice</string>
<string name="pref_title_notifications_sms">SMS</string>
<string name="pref_title_notifications_generic">Suport notificari generice</string>
<string name="pref_title_whenscreenon">... si cand ecranul este pornit</string>
<string name="always">Intotdeauna</string>
<string name="when_screen_off">Cand ecranul este oprit</string>
<string name="never">Niciodata</string>
<string name="pref_call_privacy_mode_off">Afiseaza numele si numarul</string>
<string name="pref_call_privacy_mode_name">Ascunde numele, afiseaza numarul</string>
<string name="pref_call_privacy_mode_number">Afiseaza numele, ascunde numarul</string>
<string name="pref_call_privacy_mode_complete">Ascunde numele si numarul</string>
<string name="pref_title_weather">Meteo</string>
<string name="controlcenter_take_screenshot">Captura ecran</string>
<string name="controlcenter_snackbar_disconnecting">Se deconecteaza</string>
<string name="controlcenter_snackbar_connecting">Se conecteaza</string>
<string name="controlcenter_snackbar_requested_screenshot">Capturez ecranul dispozitivului</string>
<string name="title_activity_debug">Depanare</string>
<string name="appmanager_installed_watchapps">Aplicatii instalate</string>
<string name="appmanager_installed_watchfaces">Fete de ceas instalate</string>
<string name="appmananger_app_delete">Sterge</string>
<string name="appmanager_app_openinstore">Cauta in magazinul Pebble</string>
<string name="appmanager_weather_install_provider">Instaleaza aplicatie notificari meteo</string>
<string name="app_move_to_top">Muta la inceput</string>
<string name="fw_upgrade_notice">Esti pe punctul de a instala firmware-ul %s in locul celui deja instalat pe Mi Band.</string>
<string name="fw_upgrade_notice_amazfitbip">Esti pe punctul de a instala firmware-ul %s pe Amazfit Bip.
\n
\nAi grija sa instalezi fisierul .fw, apoi fisierul .res, si in final fisierul .gps. Ceasul va reporni dupa ce se instaleaza fisierul .fw.
\n
\nNota: Nu este necesar sa instalezi fisierele .res si .gps daca aceste fisiere sunt identice cu cele instalate anterior.
\n
\nCONTINUATI PE RISCUL DUMNEAVOASTRA!</string>
<string name="fw_upgrade_notice_amazfitcor">Esti pe punctul de a instala firmware-ul %s pe Amazfit Cor.
\n
\nAi grija sa instalezi fisierul .fw, si apoi fisierul .res. Ceasul va reporni dupa ce se instaleaza fisierul .fw.
\n
\nNota: Nu este necesar sa instalezi fisierul .res daca acest fisier este identic cu cel instalat anterior.
\n
\nCONTINUATI PE RISCUL DUMNEAVOASTRA!</string>
<string name="fw_upgrade_notice_miband3">Esti pe punctul de a instala firmware-ul %s pe Mi Band 3.
\n
\nAi grija sa instalezi fisierul .fw, si apoi fisierul .res. Ceasul va reporni dupa ce se instaleaza fisierul .fw.
\n
\nNota: Nu este necesar sa instalezi fisierul .res daca acest fisier este identic cu cel instalat anterior.
\n
\nNETESTAT, V-AR PUTEA BLOCA ECHIPAMENTUL, CONTINUATI PE RISCUL DUMNEAVOASTRA!</string>
<string name="miband_firmware_unknown_warning">Acest firmware nu a fost testat si ar putea sa nu fie compatibil cu Gadgetbridge.
\n
\nTe DESCURAJAM sa-l instalezi pe Mi Band!</string>
<string name="pref_header_development">Optiuni dezvoltator</string>
<string name="pref_title_development_miaddr">Adresa Mi Band</string>
<string name="pref_title_pebble_settings">Setari Pebble</string>
<string name="pref_title_pebble_sync_misfit">Sincronizeaza Misfit</string>
<string name="pref_summary_enable_outgoing_call">Dezactivand aceasta optiune va opri Pebble 2/LE sa vibreze la apeluri</string>
<string name="pref_pebble_privacy_mode_off">Notificari normale</string>
<string name="pref_title_location_latitude">Latitudine</string>
<string name="pref_title_location_longitude">Longitudine</string>
<string name="menuitem_shortcut_weather">Meteo (Scurtatura)</string>
<string name="menuitem_activity">Activitate</string>
<string name="menuitem_weather">Meteo</string>
<string name="menuitem_alarm">Alarma</string>
<string name="menuitem_timer">Cronometru</string>
<string name="menuitem_compass">Compas</string>
<string name="menuitem_settings">Setari</string>
<string name="menuitem_alipay">Alipay</string>
</resources>

View File

@ -82,12 +82,12 @@
<string name="when_screen_off">Когда экран выключен</string>
<string name="never">Никогда</string>
<string name="pref_header_privacy">Конфиденциальность</string>
<string name="pref_title_call_privacy_mode">Вызов режима конфиденциальности</string>
<string name="pref_title_call_privacy_mode">Конфиденциальность вызовов</string>
<string name="pref_call_privacy_mode_off">Отображать имя и номер</string>
<string name="pref_call_privacy_mode_name">Скрывать имя, но отображать номер</string>
<string name="pref_call_privacy_mode_number">Скрывать номер, но отображать имя</string>
<string name="pref_call_privacy_mode_complete">Скрывать имя и номер</string>
<string name="pref_blacklist">Нежелательные приложения</string>
<string name="pref_blacklist">Заблокированные приложения</string>
<string name="pref_header_cannned_messages">Сохранённые сообщения</string>
<string name="pref_title_canned_replies">Ответы</string>
<string name="pref_title_canned_reply_suffix">Общий суффикс</string>
@ -159,7 +159,7 @@
<string name="gadgetbridge_running">Gadgetbridge запущен</string>
<string name="installing_binary_d_d">установка бинарного файла %1$d/%2$d</string>
<string name="installation_failed_">Установка не удалась</string>
<string name="installation_successful">Установка завершена</string>
<string name="installation_successful">Установлено</string>
<string name="firmware_install_warning">ВЫ ПЫТАЕТЕСЬ УСТАНОВИТЬ ПРОШИВКУ, ПРОДОЛЖАЙТЕ НА СВОЙ СТРАХ И РИСК.\n\n\n Эта прошивка для ревизии устройства: %s</string>
<string name="app_install_info">Вы собираетесь установить приложение:\n\n\n%1$s версия %2$s от %3$s\n</string>
<string name="n_a">Недоступно</string>
@ -218,7 +218,7 @@
<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>
<string name="control_center_find_lost_device">Найти потерянное устройство</string>
<string name="control_center_find_lost_device">Поиск потерянного устройства</string>
<string name="control_center_cancel_to_stop_vibration">Отмените, чтобы прекратить вибрацию.</string>
<string name="title_activity_charts">Ваша активность</string>
<string name="title_activity_set_alarm">Завести Будильник</string>
@ -236,7 +236,7 @@
<string name="user_feedback_miband_set_alarms_ok">Будильник был послан на устройство!</string>
<string name="chart_no_data_synchronize">Нет данных. Синхронизировать устройство?</string>
<string name="user_feedback_miband_activity_data_transfer">Будет передано %1$s данных, начиная с %2$s</string>
<string name="miband_prefs_fitness_goal">Цель шагов на каждый день</string>
<string name="miband_prefs_fitness_goal">Ежедневная цель шагов</string>
<string name="dbaccess_error_executing">Произошла ошибка при выполнении \'%1$s\'</string>
<string name="controlcenter_start_activitymonitor">Ваша активность (АЛЬФА)</string>
<string name="cannot_connect">Подключиться не удалось: %1$s</string>
@ -316,7 +316,7 @@
<string name="device_fw">Версия прошивки: %1$s</string>
<string name="error_creating_directory_for_logfiles">Ошибка создания каталога для лог-файлов: %1$s</string>
<string name="DEVINFO_HR_VER">"Версия устройства: "</string>
<string name="updatefirmwareoperation_update_in_progress">Происходит обновление прошивки</string>
<string name="updatefirmwareoperation_update_in_progress">Обновление прошивки</string>
<string name="updatefirmwareoperation_firmware_not_sent">Прошивка не отправлена</string>
<string name="charts_legend_heartrate">Пульс</string>
<string name="live_activity_heart_rate">Пульс</string>
@ -334,16 +334,16 @@
<string name="dbmanagementactivity_error_exporting_shared">Ошибка экспорта настроек: %1$s</string>
<string name="dbmanagementactivity_import_data_title">Импортировать данные?</string>
<string name="dbmanagementactivity_overwrite_database_confirmation">Точно перезаписать текущую базу данных? Все текущие данные вашей активности (если они есть) будут утеряны.</string>
<string name="dbmanagementactivity_import_successful">Импорт успешно завершён.</string>
<string name="dbmanagementactivity_import_successful">Импортировано.</string>
<string name="dbmanagementactivity_error_importing_db">Ошибка импорта базы данных: %1$s</string>
<string name="dbmanagementactivity_error_importing_shared">Ошибка импорта настроек: %1$s</string>
<string name="dbmanagementactivity_delete_activity_data_title">Удалить данные по вашей активности?</string>
<string name="dbmanagementactivity_really_delete_entire_db">Действительно удалить всю базу данных? Все данные о вашей активности и информация о ваших устройствах будут утеряны.</string>
<string name="dbmanagementactivity_database_successfully_deleted">Данные успешно удалены.</string>
<string name="dbmanagementactivity_database_successfully_deleted">Данные удалены.</string>
<string name="dbmanagementactivity_db_deletion_failed">Удалить базу данных не получилось.</string>
<string name="dbmanagementactivity_delete_old_activity_db">Удалить данные по предыдущей активности?</string>
<string name="dbmanagementactivity_delete_old_activitydb_confirmation">Точно удалить старые данные об активности? Все не импортированные данные об активности будут утеряны.</string>
<string name="dbmanagementactivity_old_activity_db_successfully_deleted">Устаревшие данные по вашей активности успешно удалены.</string>
<string name="dbmanagementactivity_old_activity_db_successfully_deleted">Устаревшие данные активности удалены.</string>
<string name="dbmanagementactivity_old_activity_db_deletion_failed">Удалить устаревшие данные по вашей активности не получилось.</string>
<string name="dbmanagementactivity_overwrite">Перезаписать</string>
<string name="Cancel">Отмена</string>
@ -378,7 +378,7 @@
<string name="discovery_bonding_failed_immediately">Не удалось выполнить привязку к %1$s.</string>
<string name="discovery_trying_to_connect_to">Попытка соединения с: %1$s</string>
<string name="discovery_enable_bluetooth">Включить Bluetooth для обнаружения устройств.</string>
<string name="discovery_successfully_bonded">Привязка к %1$s успешно выполнена.</string>
<string name="discovery_successfully_bonded">Связано с %1$s.</string>
<string name="discovery_pair_title">Выполнить сопряжение с %1$s ?</string>
<string name="discovery_pair_question">Выберите \"Сопряжение\" для сопряжения ваших устройств. Если не получилось, попробуйте снова без сопряжения.</string>
<string name="discovery_yes_pair">Сопряжение</string>
@ -387,19 +387,20 @@
<string name="controlcenter_connect">Подключить</string>
<string name="title_activity_calblacklist">Заблокированные календари</string>
<string name="fw_upgrade_notice_amazfitbip">"Вы собираетесь установить прошивку %s на ваш Amazfit Bip.
<string name="fw_upgrade_notice_amazfitbip">Вы собираетесь установить прошивку %s на ваш Amazfit Bip.
\n
\nСоблюдайте последовательность: вначале установите файл .fw, затем .res, и затем .gps. После установки файла .fw часы перезагрузятся.
\n
\nПеред этим, пожалуйста, установите файл .gps, файл .res и последним — .fw файл. После установки .fw файла устройство перезагрузится.
\nОбратите внимание: если файлы .gps и .res такие же, как в текущей версии, их не нужно переустанавливать.
\n
\nВы действуете на свой страх и риск!"</string>
<string name="fw_upgrade_notice_amazfitcor">Вы собираетесь установить прошивку %s на ваш Amazonfit Cor.
\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК!</string>
<string name="fw_upgrade_notice_amazfitcor">Вы собираетесь установить прошивку %s на ваш Amazfit Cor.
\n
\nПеред этим, пожалуйста, установите файл .res и файл .fw. После установки файла .fw ваше устройство перезагрузится.
\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся.
\n
\nОбратие внимание: если версия файла .res совпадает с предыдущей, его не нужно переустанавливать.
\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать.
\n
\nЭту прошивку не проверяли, поэтому есть вероятность сломать ваше устройство. Действуйте на свой страх и риск!</string>
\nВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК!</string>
<string name="pref_title_charts_swipe">Включить жесты \"провести направо и налево\" в графиках активности</string>
<string name="pref_blacklist_calendars">Заблокировать Календари</string>
@ -481,4 +482,62 @@
<string name="menuitem_weather">Погода</string>
<string name="menuitem_compass">Компас</string>
<string name="menuitem_settings">Настройки</string>
<string name="blacklist_all_for_notifications">Заблокировать все</string>
<string name="whitelist_all_for_notifications">Разблокировать все</string>
<string name="fw_upgrade_notice_miband3">Вы собираетесь установить прошивку %s на ваш Mi Band 3.
\n
\nСоблюдайте последовательность: вначале установите файл .fw, затем .res. После установки файла .fw часы перезагрузятся.
\n
\nОбратите внимание: если версия файла .res совпадает с установленной, его не нужно переустанавливать.
\n
\nНЕ ПРОВЕРЯЛОСЬ, ЕСТЬ ВЕРОЯТНОСТЬ СЛОМАТЬ ВАШЕ УСТРОЙСТВО. ВЫ ДЕЙСТВУЕТЕ НА СВОЙ СТРАХ И РИСК!</string>
<string name="pref_title_weather_location">Местоположение для погоды (CM/LOS)</string>
<string name="pref_title_pebble_gatt_clientonly">Подключаться только в режиме GATT-клиента</string>
<string name="pref_summary_pebble_gatt_clientonly">Экспериментальные настройки только для Pebble 2. Попробуйте, если есть проблемы с соединением.</string>
<string name="pref_header_auto_export">Автоматический экспорт данных</string>
<string name="pref_title_auto_export_enabled">Включить автоматический экспорт</string>
<string name="pref_title_auto_export_location">Путь экспорта</string>
<string name="pref_title_auto_export_interval">Интервал экспорта</string>
<string name="pref_summary_auto_export_interval">Экспортировать каждые %d часов</string>
<string name="spanish">Испанский</string>
<string name="russian">Русский</string>
<string name="activity_type_not_measured">Не измерялось</string>
<string name="activity_type_activity">Активность</string>
<string name="activity_type_unknown">Неизвестная активность</string>
<string name="activity_type_treadmill">Беговая дорожка</string>
<string name="kind_gps">Прошивка GPS</string>
<string name="kind_resources">Ресурсы</string>
<string name="devicetype_unknown">Неизвестное устройство</string>
<string name="devicetype_pebble">Pebble</string>
<string name="devicetype_amazfit_bip">Amazfit Bip</string>
<string name="devicetype_amazfit_cor">Amazfit Cor</string>
<string name="menuitem_shortcut_alipay">Alipay (ярлык)</string>
<string name="menuitem_alipay">Alipay</string>
<string name="on">Вкл.</string>
<string name="select_all">Выбрать все</string>
<string name="share">Поделиться</string>
<string name="kind_firmware">Прошивка</string>
<string name="menuitem_shortcut_weather">Погода (ярлык)</string>
<string name="menuitem_alarm">Будильник</string>
<string name="menuitem_timer">Таймер</string>
<string name="activity_type_biking">Велопрогулка</string>
<string name="devicetype_test">Тестовое устройство</string>
<string name="devicetype_miband">Mi Band</string>
<string name="devicetype_miband2">Mi Band 2</string>
<string name="devicetype_miband3">Mi Band 3</string>
<string name="devicetype_vibratissimo">Vibratissimo</string>
<string name="devicetype_liveview">LiveView</string>
<string name="devicetype_hplus">HPlus</string>
<string name="devicetype_makibes_f68">Makibes F68</string>
<string name="devicetype_exrizu_k8">Exrizu K8</string>
<string name="devicetype_q8">Q8</string>
<string name="devicetype_teclast_h30">Teclast H30</string>
<string name="devicetype_xwatch">XWatch</string>
<string name="devicetype_mykronoz_zetime">MyKronoz ZeTime</string>
</resources>

View File

@ -267,6 +267,7 @@
<item name="1">@string/traditional_chinese</item>
<item name="2">@string/english</item>
<item name="3">@string/spanish</item>
<item name="4">@string/russian</item>
</string-array>
<string-array name="pref_amazfitbip_language_values">
@ -275,6 +276,7 @@
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</string-array>
<string-array name="prefs_heartrate_measurement_interval">

View File

@ -427,6 +427,7 @@
<string name="traditional_chinese">Traditional Chinese</string>
<string name="english">English</string>
<string name="spanish">Spanish</string>
<string name="russian">Russian</string>
<string name="FetchActivityOperation_about_to_transfer_since">About to transfer data since %1$s</string>

View File

@ -1,5 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<changelog>
<release version="0.28.1" versioncode="135">
<change>Fix wrong weather icon mapping in rare cases</change>
<change>Fix device discovery on Android 4.4</change>
<change>Amazfit Bip: Use UTC in gpx tracks for better compatibility with external software</change>
<change>Amazfit Bip: Add the (localized) activity type to the gpx filename</change>
<change>Amazfit Bip: Fix weather on latest firmwares</change>
</release>
<release version="0.28.0" versioncode="134">
<change>Initial support for ZeTime</change>
<change>Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme</change>
<change>Amazfit Bip: Support setting language to Russian</change>
<change>Amazfit Cor: Support language switching on newer firmwares</change>
<change>Mi Band 3: support setting language (english and spanish tested)</change>
<change>Mi Band 3: Fix pairing</change>
<change>Mi Band 3: Send AQI to enable display of current temperature</change>
</release>
<release version="0.27.1" versioncode="133">
<change>Pebble: Change appstore search to point to RomanPort's pebble appstore</change>
<change>Mi Band 3: Allow flashing fonts (untested)</change>

View File

@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'com.android.tools.build:gradle:3.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@ -0,0 +1,7 @@
* Initial support for ZeTime
* Amazfit Bip/Cor: Rework firmware detection to cope with new version scheme
* Amazfit Bip: Support setting language to Russian
* Amazfit Cor: Support language switching on newer firmwares
* Mi Band 3: support setting language (english and spanish tested)
* Mi Band 3: Fix pairing
* Mi Band 3: Send AQI to enable display of current temperature

View File

@ -0,0 +1,5 @@
* Fix wrong weather icon mapping in rare cases
* Fix device discovery on Android 4.4
* Amazfit Bip: Use UTC in gpx tracks for better compatibility with external software
* Amazfit Bip: Add the (localized) activity type to the gpx filename
* Amazfit Bip: Fix weather on latest firmwares