mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-27 19:15:50 +01:00
Merge remote-tracking branch 'origin/master' into low_battery_notification
This commit is contained in:
commit
2f1aa45445
@ -1,5 +1,8 @@
|
|||||||
###Changelog
|
###Changelog
|
||||||
|
|
||||||
|
####next version
|
||||||
|
* Pebble: support "dismiss all" action also on Pebble Time/FW 3.x notifications
|
||||||
|
|
||||||
####Version 0.5.1
|
####Version 0.5.1
|
||||||
* Pebble: support taking screenshot from Pebble Time
|
* Pebble: support taking screenshot from Pebble Time
|
||||||
* Fix broken "find lost device" which was broken in 0.5.0
|
* Fix broken "find lost device" which was broken in 0.5.0
|
||||||
|
@ -33,7 +33,7 @@ public class GadgetbridgePblSupport {
|
|||||||
mPebbleProtocol = pebbleProtocol;
|
mPebbleProtocol = pebbleProtocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBDeviceEvent handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||||
int timestamp = 0;
|
int timestamp = 0;
|
||||||
for (Pair<Integer, Object> pair : pairs) {
|
for (Pair<Integer, Object> pair : pairs) {
|
||||||
switch (pair.first) {
|
switch (pair.first) {
|
||||||
@ -75,6 +75,6 @@ public class GadgetbridgePblSupport {
|
|||||||
}
|
}
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||||
sendBytes.encodedBytes = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
sendBytes.encodedBytes = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
||||||
return sendBytes;
|
return new GBDeviceEvent[]{sendBytes};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import android.util.Pair;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.SimpleTimeZone;
|
import java.util.SimpleTimeZone;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
@ -41,7 +40,6 @@ public class MorpheuzSupport {
|
|||||||
public static final UUID uuid = UUID.fromString("5be44f1d-d262-4ea6-aa30-ddbec1e3cab2");
|
public static final UUID uuid = UUID.fromString("5be44f1d-d262-4ea6-aa30-ddbec1e3cab2");
|
||||||
private final PebbleProtocol mPebbleProtocol;
|
private final PebbleProtocol mPebbleProtocol;
|
||||||
|
|
||||||
private boolean sent_to_gadgetbridge = false;
|
|
||||||
// data received from Morpheuz in native format
|
// data received from Morpheuz in native format
|
||||||
private int smartalarm_from = -1; // time in minutes relative from 0:00 for smart alarm (earliest)
|
private int smartalarm_from = -1; // time in minutes relative from 0:00 for smart alarm (earliest)
|
||||||
private int smartalarm_to = -1;// time in minutes relative from 0:00 for smart alarm (latest)
|
private int smartalarm_to = -1;// time in minutes relative from 0:00 for smart alarm (latest)
|
||||||
@ -57,21 +55,15 @@ public class MorpheuzSupport {
|
|||||||
private byte[] encodeMorpheuzMessage(int key, int value) {
|
private byte[] encodeMorpheuzMessage(int key, int value) {
|
||||||
ArrayList<Pair<Integer, Object>> pairs = new ArrayList<>();
|
ArrayList<Pair<Integer, Object>> pairs = new ArrayList<>();
|
||||||
pairs.add(new Pair<Integer, Object>(key, value));
|
pairs.add(new Pair<Integer, Object>(key, value));
|
||||||
byte[] ackMessage = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
|
||||||
byte[] testMessage = mPebbleProtocol.encodeApplicationMessagePush(PebbleProtocol.ENDPOINT_APPLICATIONMESSAGE, uuid, pairs);
|
|
||||||
|
|
||||||
ByteBuffer buf = ByteBuffer.allocate(ackMessage.length + testMessage.length);
|
return mPebbleProtocol.encodeApplicationMessagePush(PebbleProtocol.ENDPOINT_APPLICATIONMESSAGE, uuid, pairs);
|
||||||
|
|
||||||
// encode ack and put in front of push message (hack for acknowledging the last message)
|
|
||||||
buf.put(ackMessage);
|
|
||||||
buf.put(testMessage);
|
|
||||||
|
|
||||||
return buf.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBDeviceEvent handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||||
for (Pair<Integer, Object> pair : pairs) {
|
|
||||||
int ctrl_message = 0;
|
int ctrl_message = 0;
|
||||||
|
GBDeviceEventSleepMonitorResult sleepMonitorResult = null;
|
||||||
|
|
||||||
|
for (Pair<Integer, Object> pair : pairs) {
|
||||||
switch (pair.first) {
|
switch (pair.first) {
|
||||||
case KEY_TRANSMIT:
|
case KEY_TRANSMIT:
|
||||||
case KEY_GONEOFF:
|
case KEY_GONEOFF:
|
||||||
@ -79,22 +71,11 @@ public class MorpheuzSupport {
|
|||||||
alarm_gone_off = (int) pair.second;
|
alarm_gone_off = (int) pair.second;
|
||||||
LOG.info("got gone off: " + alarm_gone_off / 60 + ":" + alarm_gone_off % 60);
|
LOG.info("got gone off: " + alarm_gone_off / 60 + ":" + alarm_gone_off % 60);
|
||||||
}
|
}
|
||||||
/* super-ugly hack: if if did not notice GadgetBridge yet, do so and delay confirmation so Morpheuz
|
sleepMonitorResult = new GBDeviceEventSleepMonitorResult();
|
||||||
* will resend gone off data. The second time, we acknowledge it.
|
|
||||||
*
|
|
||||||
* this can be fixed by allowing to return multiple GBDeviceCommands
|
|
||||||
*/
|
|
||||||
if (sent_to_gadgetbridge) {
|
|
||||||
ctrl_message = MorpheuzSupport.CTRL_VERSION_DONE | MorpheuzSupport.CTRL_GONEOFF_DONE | MorpheuzSupport.CTRL_TRANSMIT_DONE | MorpheuzSupport.CTRL_SET_LAST_SENT;
|
|
||||||
} else {
|
|
||||||
GBDeviceEventSleepMonitorResult sleepMonitorResult = new GBDeviceEventSleepMonitorResult();
|
|
||||||
sleepMonitorResult.smartalarm_from = smartalarm_from;
|
sleepMonitorResult.smartalarm_from = smartalarm_from;
|
||||||
sleepMonitorResult.smartalarm_to = smartalarm_to;
|
sleepMonitorResult.smartalarm_to = smartalarm_to;
|
||||||
sleepMonitorResult.alarm_gone_off = alarm_gone_off;
|
sleepMonitorResult.alarm_gone_off = alarm_gone_off;
|
||||||
sleepMonitorResult.recording_base_timestamp = recording_base_timestamp;
|
sleepMonitorResult.recording_base_timestamp = recording_base_timestamp;
|
||||||
sent_to_gadgetbridge = true;
|
|
||||||
return sleepMonitorResult;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KEY_POINT:
|
case KEY_POINT:
|
||||||
if (recording_base_timestamp == -1) {
|
if (recording_base_timestamp == -1) {
|
||||||
@ -140,7 +121,6 @@ public class MorpheuzSupport {
|
|||||||
case KEY_VERSION:
|
case KEY_VERSION:
|
||||||
LOG.info("got version: " + ((float) ((int) pair.second) / 10.0f));
|
LOG.info("got version: " + ((float) ((int) pair.second) / 10.0f));
|
||||||
ctrl_message = MorpheuzSupport.CTRL_VERSION_DONE | MorpheuzSupport.CTRL_SET_LAST_SENT;
|
ctrl_message = MorpheuzSupport.CTRL_VERSION_DONE | MorpheuzSupport.CTRL_SET_LAST_SENT;
|
||||||
sent_to_gadgetbridge = false;
|
|
||||||
break;
|
break;
|
||||||
case KEY_BASE:
|
case KEY_BASE:
|
||||||
// fix timestamp
|
// fix timestamp
|
||||||
@ -156,14 +136,20 @@ public class MorpheuzSupport {
|
|||||||
LOG.info("unhandled key: " + pair.first);
|
LOG.info("unhandled key: " + pair.first);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// always ack
|
||||||
|
GBDeviceEventSendBytes sendBytesAck = new GBDeviceEventSendBytes();
|
||||||
|
sendBytesAck.encodedBytes = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
||||||
|
|
||||||
|
// sometimes send control message
|
||||||
|
GBDeviceEventSendBytes sendBytesCtrl = null;
|
||||||
if (ctrl_message > 0) {
|
if (ctrl_message > 0) {
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
sendBytesCtrl = new GBDeviceEventSendBytes();
|
||||||
sendBytes.encodedBytes = encodeMorpheuzMessage(MorpheuzSupport.KEY_CTRL, ctrl_message);
|
sendBytesCtrl.encodedBytes = encodeMorpheuzMessage(MorpheuzSupport.KEY_CTRL, ctrl_message);
|
||||||
return sendBytes;
|
}
|
||||||
}
|
|
||||||
}
|
// ctrl and sleep monitor might be null, thats okay
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
return new GBDeviceEvent[]{sendBytesAck, sendBytesCtrl, sleepMonitorResult};
|
||||||
sendBytes.encodedBytes = mPebbleProtocol.encodeApplicationMessageAck(uuid, mPebbleProtocol.last_id);
|
|
||||||
return sendBytes;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,14 +237,19 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
|||||||
mInStream.skip(2);
|
mInStream.skip(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
GBDeviceEvent deviceEvent = mPebbleProtocol.decodeResponse(buffer);
|
GBDeviceEvent deviceEvents[] = mPebbleProtocol.decodeResponse(buffer);
|
||||||
if (deviceEvent == null) {
|
if (deviceEvents == null) {
|
||||||
LOG.info("unhandled message to endpoint " + endpoint + " (" + length + " bytes)");
|
LOG.info("unhandled message to endpoint " + endpoint + " (" + length + " bytes)");
|
||||||
} else {
|
} else {
|
||||||
|
for (GBDeviceEvent deviceEvent : deviceEvents) {
|
||||||
|
if (deviceEvent == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!evaluateGBDeviceEventPebble(deviceEvent)) {
|
if (!evaluateGBDeviceEventPebble(deviceEvent)) {
|
||||||
mPebbleSupport.evaluateGBDeviceEvent(deviceEvent);
|
mPebbleSupport.evaluateGBDeviceEvent(deviceEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -95,6 +95,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
static final byte MUSICCONTROL_VOLUMEDOWN = 7;
|
static final byte MUSICCONTROL_VOLUMEDOWN = 7;
|
||||||
static final byte MUSICCONTROL_GETNOWPLAYING = 7;
|
static final byte MUSICCONTROL_GETNOWPLAYING = 7;
|
||||||
|
|
||||||
|
static final byte NOTIFICATIONACTION_ACK = 0;
|
||||||
|
static final byte NOTIFICATIONACTION_NACK = 1;
|
||||||
|
static final byte NOTIFICATIONACTION_INVOKE = 0x02;
|
||||||
|
static final byte NOTIFICATIONACTION_RESPONSE = 0x11;
|
||||||
|
|
||||||
static final byte TIME_GETTIME = 0;
|
static final byte TIME_GETTIME = 0;
|
||||||
static final byte TIME_SETTIME = 2;
|
static final byte TIME_SETTIME = 2;
|
||||||
static final byte TIME_SETTIME_UTC = 3;
|
static final byte TIME_SETTIME_UTC = 3;
|
||||||
@ -524,21 +529,22 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
private byte[] encodeBlobdbNotification(int timestamp, String title, String subtitle, String body, byte type) {
|
private byte[] encodeBlobdbNotification(int timestamp, String title, String subtitle, String body, byte type) {
|
||||||
String[] parts = {title, subtitle, body};
|
String[] parts = {title, subtitle, body};
|
||||||
|
|
||||||
int icon_id = 1;
|
int icon_id = 0x80000000 | 1;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NOTIFICATION_EMAIL:
|
case NOTIFICATION_EMAIL:
|
||||||
icon_id = 19;
|
icon_id = 0x80000000 | 19;
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_SMS:
|
case NOTIFICATION_SMS:
|
||||||
icon_id = 45;
|
icon_id = 0x80000000 | 45;
|
||||||
}
|
}
|
||||||
// Calculate length first
|
// Calculate length first
|
||||||
final short NOTIFICATION_PIN_LENGTH = 46;
|
final short NOTIFICATION_PIN_LENGTH = 46;
|
||||||
final short ACTIONS_LENGTH = 17;
|
final short ACTIONS_LENGTH = 17;
|
||||||
|
|
||||||
byte attributes_count = 1; // icon
|
byte attributes_count = 1; // icon
|
||||||
|
byte actions_count = 1; // dismiss
|
||||||
|
|
||||||
short attributes_length = 7; // icon
|
short attributes_length = 7 + ACTIONS_LENGTH; // icon
|
||||||
if (parts != null) {
|
if (parts != null) {
|
||||||
for (String s : parts) {
|
for (String s : parts) {
|
||||||
if (s == null || s.equals("")) {
|
if (s == null || s.equals("")) {
|
||||||
@ -549,13 +555,6 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte actions_count = 0;
|
|
||||||
|
|
||||||
if (mForceProtocol) {
|
|
||||||
actions_count = 1;
|
|
||||||
attributes_length += ACTIONS_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
short pin_length = (short) (NOTIFICATION_PIN_LENGTH + attributes_length);
|
short pin_length = (short) (NOTIFICATION_PIN_LENGTH + attributes_length);
|
||||||
|
|
||||||
@ -598,20 +597,39 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
buf.putShort((short) 4); // length of int
|
buf.putShort((short) 4); // length of int
|
||||||
buf.putInt(icon_id);
|
buf.putInt(icon_id);
|
||||||
|
|
||||||
if (mForceProtocol) {
|
|
||||||
// ACTION
|
// ACTION
|
||||||
buf.put((byte) 0x01); // id
|
buf.put((byte) 0x01); // id
|
||||||
buf.put((byte) 0x04); // dismiss action
|
buf.put((byte) 0x02); // generic action, dismiss did not do anything
|
||||||
buf.put((byte) 0x01); // number attributes
|
buf.put((byte) 0x01); // number attributes
|
||||||
buf.put((byte) 0x01); // attribute id (title)
|
buf.put((byte) 0x01); // attribute id (title)
|
||||||
String actionstring = "dismiss all";
|
String actionstring = "dismiss all";
|
||||||
buf.putShort((short) actionstring.length());
|
buf.putShort((short) actionstring.length());
|
||||||
buf.put(actionstring.getBytes());
|
buf.put(actionstring.getBytes());
|
||||||
}
|
|
||||||
|
|
||||||
return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array());
|
return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] encodeActionResponse(UUID uuid) {
|
||||||
|
short length = 38;
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length);
|
||||||
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
buf.putShort(length);
|
||||||
|
buf.putShort(ENDPOINT_NOTIFICATIONACTION);
|
||||||
|
buf.put(NOTIFICATIONACTION_RESPONSE);
|
||||||
|
buf.putLong(uuid.getMostSignificantBits());
|
||||||
|
buf.putLong(uuid.getLeastSignificantBits());
|
||||||
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
buf.put(NOTIFICATIONACTION_ACK);
|
||||||
|
buf.put((byte) 2); //nr of attributes
|
||||||
|
buf.put((byte) 6); // icon
|
||||||
|
buf.putShort((short) 4); // length
|
||||||
|
buf.putInt(0x80000033); // icon id
|
||||||
|
buf.put((byte) 2); // title
|
||||||
|
buf.putShort((short) 9); // length
|
||||||
|
buf.put("Dismissed".getBytes());
|
||||||
|
return buf.array();
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] encodeInstallMetadata(UUID uuid, String appName, short appVersion, short sdkVersion, int flags, int iconId) {
|
public byte[] encodeInstallMetadata(UUID uuid, String appName, short appVersion, short sdkVersion, int flags, int iconId) {
|
||||||
final short METADATA_LENGTH = 126;
|
final short METADATA_LENGTH = 126;
|
||||||
|
|
||||||
@ -1059,15 +1077,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GBDeviceEventDismissNotification decodeNotificationAction(ByteBuffer buf) {
|
private GBDeviceEventDismissNotification decodeNotificationAction2x(ByteBuffer buf) {
|
||||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
byte command = buf.get();
|
byte command = buf.get();
|
||||||
if (command == 0x02) { // dismiss notification ?
|
if (command == 0x02) { // dismiss notification ?
|
||||||
if (isFw3x) {
|
|
||||||
buf.getLong(); // skip 8 bytes of UUID
|
|
||||||
buf.getInt(); // skip 4 bytes of UUID
|
|
||||||
}
|
|
||||||
int id = buf.getInt();
|
int id = buf.getInt();
|
||||||
short action = buf.getShort(); // at least the low byte should be the action - or not?
|
short action = buf.getShort(); // at least the low byte should be the action - or not?
|
||||||
if (action == 0x0001) {
|
if (action == 0x0001) {
|
||||||
@ -1081,6 +1095,29 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GBDeviceEvent[] decodeNotificationAction3x(ByteBuffer buf) {
|
||||||
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
byte command = buf.get();
|
||||||
|
if (command == NOTIFICATIONACTION_INVOKE) {
|
||||||
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
long uuid_high = buf.getLong();
|
||||||
|
long uuid_low = buf.getLong();
|
||||||
|
int id = (int) (uuid_low & 0xffff);
|
||||||
|
byte action = buf.get();
|
||||||
|
if (action == 0x01) {
|
||||||
|
GBDeviceEventDismissNotification dismissNotification = new GBDeviceEventDismissNotification();
|
||||||
|
dismissNotification.notificationID = id;
|
||||||
|
GBDeviceEventSendBytes sendBytesAck = new GBDeviceEventSendBytes();
|
||||||
|
sendBytesAck.encodedBytes = encodeActionResponse(new UUID(uuid_high, uuid_low));
|
||||||
|
return new GBDeviceEvent[]{sendBytesAck, dismissNotification};
|
||||||
|
}
|
||||||
|
LOG.info("unexpected action: " + action);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private GBDeviceEventSendBytes decodePing(ByteBuffer buf) {
|
private GBDeviceEventSendBytes decodePing(ByteBuffer buf) {
|
||||||
byte command = buf.get();
|
byte command = buf.get();
|
||||||
if (command == PING_PING) {
|
if (command == PING_PING) {
|
||||||
@ -1114,16 +1151,17 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
private GBDeviceEventSendBytes decodeDatalog(ByteBuffer buf, short length) {
|
private GBDeviceEventSendBytes decodeDatalog(ByteBuffer buf, short length) {
|
||||||
byte command = buf.get();
|
byte command = buf.get();
|
||||||
byte id = buf.get();
|
byte id = buf.get();
|
||||||
if (command == DATALOG_TIMEOUT) {
|
switch (command) {
|
||||||
|
case DATALOG_TIMEOUT:
|
||||||
LOG.info("DATALOG TIMEOUT. id=" + (id & 0xff) + " - ignoring");
|
LOG.info("DATALOG TIMEOUT. id=" + (id & 0xff) + " - ignoring");
|
||||||
return null;
|
return null;
|
||||||
}
|
case DATALOG_SENDDATA:
|
||||||
if (command == DATALOG_SENDDATA) {
|
|
||||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
int items_left = buf.getInt();
|
int items_left = buf.getInt();
|
||||||
int crc = buf.getInt();
|
int crc = buf.getInt();
|
||||||
LOG.info("DATALOG SENDDATA. id=" + (id & 0xff) + ", items_left=" + items_left + ", total length=" + (length - 9));
|
LOG.info("DATALOG SENDDATA. id=" + (id & 0xff) + ", items_left=" + items_left + ", total length=" + (length - 9));
|
||||||
} else if (command == DATALOG_OPENSESSION) {
|
break;
|
||||||
|
case DATALOG_OPENSESSION:
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
long uuid_high = buf.getLong();
|
long uuid_high = buf.getLong();
|
||||||
long uuid_low = buf.getLong();
|
long uuid_low = buf.getLong();
|
||||||
@ -1134,6 +1172,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
byte item_type = buf.get();
|
byte item_type = buf.get();
|
||||||
short item_size = buf.get();
|
short item_size = buf.get();
|
||||||
LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", item_type=" + item_type + ", item_size=" + item_size);
|
LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", item_type=" + item_type + ", item_size=" + item_size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG.info("unknown DATALOG command: " + (command & 0xff));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
LOG.info("sending ACK (0x85)");
|
LOG.info("sending ACK (0x85)");
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||||
@ -1142,12 +1184,12 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GBDeviceEvent decodeResponse(byte[] responseData) {
|
public GBDeviceEvent[] decodeResponse(byte[] responseData) {
|
||||||
ByteBuffer buf = ByteBuffer.wrap(responseData);
|
ByteBuffer buf = ByteBuffer.wrap(responseData);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
short length = buf.getShort();
|
short length = buf.getShort();
|
||||||
short endpoint = buf.getShort();
|
short endpoint = buf.getShort();
|
||||||
GBDeviceEvent devEvt = null;
|
GBDeviceEvent devEvts[] = null;
|
||||||
byte pebbleCmd = -1;
|
byte pebbleCmd = -1;
|
||||||
switch (endpoint) {
|
switch (endpoint) {
|
||||||
case ENDPOINT_MUSICCONTROL:
|
case ENDPOINT_MUSICCONTROL:
|
||||||
@ -1178,7 +1220,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
devEvt = musicCmd;
|
devEvts = new GBDeviceEvent[]{musicCmd};
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_PHONECONTROL:
|
case ENDPOINT_PHONECONTROL:
|
||||||
pebbleCmd = buf.get();
|
pebbleCmd = buf.get();
|
||||||
@ -1191,7 +1233,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
LOG.info("Unknown PHONECONTROL event" + pebbleCmd);
|
LOG.info("Unknown PHONECONTROL event" + pebbleCmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
devEvt = callCmd;
|
devEvts = new GBDeviceEvent[]{callCmd};
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_FIRMWAREVERSION:
|
case ENDPOINT_FIRMWAREVERSION:
|
||||||
pebbleCmd = buf.get();
|
pebbleCmd = buf.get();
|
||||||
@ -1213,7 +1255,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
} else if (hwRev == -3) { // basalt emulator
|
} else if (hwRev == -3) { // basalt emulator
|
||||||
versionCmd.hwVersion = "dvt";
|
versionCmd.hwVersion = "dvt";
|
||||||
}
|
}
|
||||||
devEvt = versionCmd;
|
devEvts = new GBDeviceEvent[]{versionCmd};
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_APPMANAGER:
|
case ENDPOINT_APPMANAGER:
|
||||||
pebbleCmd = buf.get();
|
pebbleCmd = buf.get();
|
||||||
@ -1253,12 +1295,12 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
devEvt = appInfoCmd;
|
devEvts = new GBDeviceEvent[]{appInfoCmd};
|
||||||
break;
|
break;
|
||||||
case APPMANAGER_GETUUIDS:
|
case APPMANAGER_GETUUIDS:
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||||
sendBytes.encodedBytes = encodeSimpleMessage(ENDPOINT_APPMANAGER, APPMANAGER_GETAPPBANKSTATUS);
|
sendBytes.encodedBytes = encodeSimpleMessage(ENDPOINT_APPMANAGER, APPMANAGER_GETAPPBANKSTATUS);
|
||||||
devEvt = sendBytes;
|
devEvts = new GBDeviceEvent[]{sendBytes};
|
||||||
tmpUUIDS.clear();
|
tmpUUIDS.clear();
|
||||||
slotsUsed = buf.getInt();
|
slotsUsed = buf.getInt();
|
||||||
for (int i = 0; i < slotsUsed; i++) {
|
for (int i = 0; i < slotsUsed; i++) {
|
||||||
@ -1282,7 +1324,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
deleteRes.event = GBDeviceEventAppManagement.Event.FAILURE;
|
deleteRes.event = GBDeviceEventAppManagement.Event.FAILURE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
devEvt = deleteRes;
|
devEvts = new GBDeviceEvent[]{deleteRes};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG.info("Unknown APPMANAGER event" + pebbleCmd);
|
LOG.info("Unknown APPMANAGER event" + pebbleCmd);
|
||||||
@ -1303,7 +1345,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
installRes.event = GBDeviceEventAppManagement.Event.FAILURE;
|
installRes.event = GBDeviceEventAppManagement.Event.FAILURE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
devEvt = installRes;
|
devEvts = new GBDeviceEvent[]{installRes};
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_APPLICATIONMESSAGE:
|
case ENDPOINT_APPLICATIONMESSAGE:
|
||||||
pebbleCmd = buf.get();
|
pebbleCmd = buf.get();
|
||||||
@ -1317,13 +1359,13 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
LOG.info("got APPLICATIONMESSAGE PUSH from UUID " + uuid);
|
LOG.info("got APPLICATIONMESSAGE PUSH from UUID " + uuid);
|
||||||
if (WeatherNeatSupport.uuid.equals(uuid)) {
|
if (WeatherNeatSupport.uuid.equals(uuid)) {
|
||||||
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
||||||
devEvt = mWeatherNeatSupport.handleMessage(dict);
|
devEvts = mWeatherNeatSupport.handleMessage(dict);
|
||||||
} else if (MorpheuzSupport.uuid.equals(uuid)) {
|
} else if (MorpheuzSupport.uuid.equals(uuid)) {
|
||||||
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
||||||
devEvt = mMorpheuzSupport.handleMessage(dict);
|
devEvts = mMorpheuzSupport.handleMessage(dict);
|
||||||
} else if (GadgetbridgePblSupport.uuid.equals(uuid)) {
|
} else if (GadgetbridgePblSupport.uuid.equals(uuid)) {
|
||||||
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
ArrayList<Pair<Integer, Object>> dict = decodeDict(buf);
|
||||||
devEvt = mGadgetbridgePblSupport.handleMessage(dict);
|
devEvts = mGadgetbridgePblSupport.handleMessage(dict);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case APPLICATIONMESSAGE_ACK:
|
case APPLICATIONMESSAGE_ACK:
|
||||||
@ -1346,33 +1388,35 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
LOG.info("Pebble asked for Phone/App Version - repLYING!");
|
LOG.info("Pebble asked for Phone/App Version - repLYING!");
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||||
sendBytes.encodedBytes = encodePhoneVersion(PHONEVERSION_REMOTE_OS_ANDROID);
|
sendBytes.encodedBytes = encodePhoneVersion(PHONEVERSION_REMOTE_OS_ANDROID);
|
||||||
devEvt = sendBytes;
|
devEvts = new GBDeviceEvent[]{sendBytes};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_DATALOG:
|
case ENDPOINT_DATALOG:
|
||||||
devEvt = decodeDatalog(buf, length);
|
devEvts = new GBDeviceEvent[]{decodeDatalog(buf, length)};
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_SCREENSHOT:
|
case ENDPOINT_SCREENSHOT:
|
||||||
devEvt = decodeScreenshot(buf, length);
|
devEvts = new GBDeviceEvent[]{decodeScreenshot(buf, length)};
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_EXTENSIBLENOTIFS:
|
case ENDPOINT_EXTENSIBLENOTIFS:
|
||||||
|
devEvts = new GBDeviceEvent[]{decodeNotificationAction2x(buf)};
|
||||||
|
break;
|
||||||
case ENDPOINT_NOTIFICATIONACTION:
|
case ENDPOINT_NOTIFICATIONACTION:
|
||||||
devEvt = decodeNotificationAction(buf);
|
devEvts = decodeNotificationAction3x(buf);
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_PING:
|
case ENDPOINT_PING:
|
||||||
devEvt = decodePing(buf);
|
devEvts = new GBDeviceEvent[]{decodePing(buf)};
|
||||||
break;
|
break;
|
||||||
case ENDPOINT_APPFETCH:
|
case ENDPOINT_APPFETCH:
|
||||||
devEvt = decodeAppFetch(buf);
|
devEvts = new GBDeviceEvent[]{decodeAppFetch(buf)};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return devEvt;
|
return devEvts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setForceProtocol(boolean force) {
|
public void setForceProtocol(boolean force) {
|
||||||
|
@ -48,9 +48,9 @@ public class WeatherNeatSupport {
|
|||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBDeviceEvent handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||||
sendBytes.encodedBytes = encodeWeatherNeatMessage("Berlin", "22 C", "cloudy", 0);
|
sendBytes.encodedBytes = encodeWeatherNeatMessage("Berlin", "22 C", "cloudy", 0);
|
||||||
return sendBytes;
|
return new GBDeviceEvent[] {sendBytes};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ public abstract class GBDeviceProtocol {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBDeviceEvent decodeResponse(byte[] responseData) {
|
public GBDeviceEvent[] decodeResponse(byte[] responseData) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
146
app/src/main/res/values-fr/strings.xml
Normal file
146
app/src/main/res/values-fr/strings.xml
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
<?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">Paramètre</string>
|
||||||
|
<string name="action_debug">Débugger</string>
|
||||||
|
<string name="action_quit">Quitter</string>
|
||||||
|
<string name="controlcenter_fetch_activity_data">Synchroniser</string>
|
||||||
|
<string name="controlcenter_start_sleepmonitor">Moniteur de sommeil (ALPHA)</string>
|
||||||
|
<string name="controlcenter_find_device">Trouver l\'appareil</string>
|
||||||
|
<string name="controlcenter_take_screenshot">Prendre une capture d\'écran</string>
|
||||||
|
<string name="controlcenter_disconnect">Déconnexion</string>
|
||||||
|
<string name="title_activity_debug">Débugger</string>
|
||||||
|
<!--Strings related to AppManager-->
|
||||||
|
<string name="appmananger_app_delete">Supprimer</string>
|
||||||
|
<!--Strings related to FwAppInstaller-->
|
||||||
|
<string name="fw_upgrade_notice">Vous êtes sur le point d\'installer le firmware %s à la place de celui qui est actuellement sur votre MiBand.</string>
|
||||||
|
<string name="miband_firmware_known">Ce firmware a été testé et est compatible with GadgetBridge</string>
|
||||||
|
<string name="miband_firmware_unknown_warning">Ce firmware n\'est pas testé and peut ne pas être compatible avec GadgetBridge. Il ne vous est pas conseillé de flasher votre MiBand</string>
|
||||||
|
<!--Strings related to Settings-->
|
||||||
|
<string name="title_activity_settings">Paramètre</string>
|
||||||
|
<string name="pref_header_general">Paramètres généraux</string>
|
||||||
|
<string name="pref_title_general_autoconnectonbluetooth">Connecter votre appareil quand le Bluetooth est mise en marche</string>
|
||||||
|
<string name="pref_header_datetime">Date et heure</string>
|
||||||
|
<string name="pref_title_datetime_syctimeonconnect">Synchroniser l\'horloge</string>
|
||||||
|
<string name="pref_summary_datetime_syctimeonconnect">Synchroniser l\'horloge lors de la connexion et quand l\'heure ou lorsque le fuseau horaire change sur Android</string>
|
||||||
|
<string name="pref_header_notifications">Notifications</string>
|
||||||
|
<string name="pref_title_notifications_repetitions">Répétitions</string>
|
||||||
|
<string name="pref_title_notifications_sms">SMS</string>
|
||||||
|
<string name="pref_title_notifications_incoming_call">Appel entrant</string>
|
||||||
|
<string name="pref_title_notifications_k9mail">K9-Email</string>
|
||||||
|
<string name="pref_title_notifications_pebblemsg">Message Pebble</string>
|
||||||
|
<string name="pref_title_notifications_generic">Support des notififactions génériques</string>
|
||||||
|
<string name="pref_title_whenscreenon">même lorsque l\'écran est allumé</string>
|
||||||
|
<string name="always">toujours</string>
|
||||||
|
<string name="when_screen_off">quand l\'écran est éteint</string>
|
||||||
|
<string name="never">jamais</string>
|
||||||
|
<string name="pref_header_development">Options développeur</string>
|
||||||
|
<string name="pref_title_development_miaddr">Adresse Mi Band</string>
|
||||||
|
<string name="pref_title_pebble_settings">Paramètres Pebble</string>
|
||||||
|
<string name="pref_title_pebble_forceprotocol">Protocole des notifications en vigueur</string>
|
||||||
|
<string name="pref_summary_pebble_forceprotocol">Cette option force l\'utilisant du dernier protocole de notification qui dépend de la verrsion du firmware. ACTIVER LA UNIQUEMENT SI VOUS SAVEZ CE QUE VOUS FAITES!</string>
|
||||||
|
<string name="pref_title_pebble_forceuntested">Activités les fonctionnalités non testé</string>
|
||||||
|
<string name="pref_summary_pebble_forceuntested">Activer les fonctionnalités non testés</string>
|
||||||
|
<string name="not_connected">non connecté</string>
|
||||||
|
<string name="connecting">en train de se connecter</string>
|
||||||
|
<string name="connected">connecté</string>
|
||||||
|
<string name="unknown_state">état inconnu</string>
|
||||||
|
<string name="connectionstate_hw_fw">HW: %1$s FW: %2$s</string>
|
||||||
|
<string name="connectionstate_fw">FW: %1$s</string>
|
||||||
|
<string name="_unknown_">(inconnu)</string>
|
||||||
|
<string name="test">Test</string>
|
||||||
|
<string name="test_notification">Notification de test</string>
|
||||||
|
<string name="this_is_a_test_notification_from_gadgetbridge">Ceci est un test de notification venant de Gadgetbridge</string>
|
||||||
|
<string name="bluetooth_is_not_supported_">Le bluetooth n\'est pas supporté</string>
|
||||||
|
<string name="bluetooth_is_disabled_">Le bluetooth est désactivé</string>
|
||||||
|
<string name="tap_a_device_to_connect">Tapper sur l\'appareil pour le connecter</string>
|
||||||
|
<string name="cannot_connect_bt_address_invalid_">Ne peut être connecter. L’adresse bluetooth est invalide? </string>
|
||||||
|
<string name="gadgetbridge_running">Gadgetbridge est en fonctionnement</string>
|
||||||
|
<string name="battery_low">faible</string>
|
||||||
|
<string name="battery_medium">moyen</string>
|
||||||
|
<string name="battery_full">plein</string>
|
||||||
|
<string name="battery_not_charging">Ne charge pas</string>
|
||||||
|
<string name="installing_binary_d_d">Installation du binaire %1$d/%2$d</string>
|
||||||
|
<string name="installation_failed_">installation en échec</string>
|
||||||
|
<string name="installation_successful">installation réalisé</string>
|
||||||
|
<string name="firmware_install_warning">VOUS ÊTES EN TRAIN D\'INSTALLER UN FIRMWARE, PROCEDEZ À VOS PROPRES RISQUES. CE FIRMWARE EST POUR LA VERSION HW: %s</string>
|
||||||
|
<string name="n_a">N/A</string>
|
||||||
|
<string name="initialized">initialisé</string>
|
||||||
|
<string name="appversion_by_creator">%1$s par %2$s</string>
|
||||||
|
<string name="title_activity_discovery">Décourir les appareils</string>
|
||||||
|
<string name="discovery_stop_scanning">Arreter de scanner</string>
|
||||||
|
<string name="discovery_start_scanning">Démarrer le scan</string>
|
||||||
|
<string name="action_discover">Découvrir l\'appareil</string>
|
||||||
|
<string name="device_with_rssi">%1$s (%2$s)</string>
|
||||||
|
<string name="title_activity_android_pairing">Coupler l\'appareil</string>
|
||||||
|
<string name="android_pairing_hint">Utiliser l\'appareillage bluetouth d\'android pour coupler l\'appareil</string>
|
||||||
|
<string name="title_activity_mi_band_pairing">Coupler votre Mi Band</string>
|
||||||
|
<string name="miband_pairing">Coupler avec %s...</string>
|
||||||
|
<string name="message_cannot_pair_no_mac">Aucune adresse mac fournis, ne peut être couplé</string>
|
||||||
|
<string name="preferences_category_device_specific_settings">Paramètres spécifique à l\'appareil </string>
|
||||||
|
<string name="preferences_miband_settings">Paramètres Mi Band</string>
|
||||||
|
<string name="male">homme</string>
|
||||||
|
<string name="female">femme</string>
|
||||||
|
<string name="other">autre</string>
|
||||||
|
<string name="left">gauche</string>
|
||||||
|
<string name="right">droite</string>
|
||||||
|
<string name="miband_pairing_using_dummy_userdata">Aucune donnée utilisateur valide fournis, utilisation des données fictives pour le moment</string>
|
||||||
|
<string name="miband_pairing_tap_hint">Quand votre Mi Band vibre et clignote, appuyez dessus plusieurs fois d\'affilée.</string>
|
||||||
|
<string name="appinstaller_install">Installer</string>
|
||||||
|
<string name="discovery_connected_devices_hint">Rendre votre appareil découvrable. Actuellement les appareils connectés ne seront pas découvert.</string>
|
||||||
|
<string name="discovery_note">Note:</string>
|
||||||
|
<string name="miband_prefs_about_you">A propos de vous</string>
|
||||||
|
<string name="miband_prefs_alias">Nom/Pseudo</string>
|
||||||
|
<string name="miband_prefs_year_birth">Année de naissance</string>
|
||||||
|
<string name="miband_prefs_gender">Genre</string>
|
||||||
|
<string name="miband_prefs_height_cm">Taille en cm</string>
|
||||||
|
<string name="miband_prefs_weight_kg">Poids en kg</string>
|
||||||
|
<string name="pref_header_vibration_count">Nombre de vibration</string>
|
||||||
|
<string name="title_activity_sleepmonitor">Moniteur de sommeil</string>
|
||||||
|
<string name="pref_write_logfiles">Ecrire le fichier de logs (besoin de redemarrer)</string>
|
||||||
|
<string name="initializing">iniitialisation</string>
|
||||||
|
<string name="sleep_activity_date_range">De %1$s à %2$s</string>
|
||||||
|
<string name="miband_prefs_wearside">Port main gauche ou droite?</string>
|
||||||
|
<string name="pref_screen_vibration_profile">Profil de vibration</string>
|
||||||
|
<string name="vibration_profile_staccato">Saccadé</string>
|
||||||
|
<string name="vibration_profile_short">Court</string>
|
||||||
|
<string name="vibration_profile_medium">Moyen</string>
|
||||||
|
<string name="vibration_profile_long">Long</string>
|
||||||
|
<string name="vibration_profile_waterdrop">Goute d\'eau</string>
|
||||||
|
<string name="vibration_profile_ring">Cycle</string>
|
||||||
|
<string name="vibration_profile_alarm_clock">Réveil</string>
|
||||||
|
<string name="miband_prefs_vibration">Vibration</string>
|
||||||
|
<string name="pref_screen_notification_profile_sms">Notification SMS</string>
|
||||||
|
<string name="pref_header_vibration_settings">Paramètres des vibrations</string>
|
||||||
|
<string name="pref_screen_notification_profile_generic">Notification génériques</string>
|
||||||
|
<string name="pref_screen_notification_profile_pebblemsg">Notification Pebble</string>
|
||||||
|
<string name="pref_screen_notification_profile_k9mail">Notification des emails K9</string>
|
||||||
|
<string name="pref_screen_notification_profile_incoming_call">Notification des appels entrant</string>
|
||||||
|
<string name="control_center_find_lost_device">Trouver l\'appareil perdu</string>
|
||||||
|
<string name="control_center_cancel_to_stop_vibration">Annuler pour arreter les vibrations</string>
|
||||||
|
<string name="title_activity_charts">Votre activité</string>
|
||||||
|
<string name="title_activity_set_alarm">Configurer les réveils</string>
|
||||||
|
<string name="controlcenter_start_configure_alarms">Configurer les réveils</string>
|
||||||
|
<string name="title_activity_alarm_details">Détails des alarmes</string>
|
||||||
|
<string name="alarm_sun_short">Dim</string>
|
||||||
|
<string name="alarm_mon_short">Lun</string>
|
||||||
|
<string name="alarm_tue_short">Mar</string>
|
||||||
|
<string name="alarm_wed_short">Mer</string>
|
||||||
|
<string name="alarm_thu_short">Jeu</string>
|
||||||
|
<string name="alarm_fri_short">Ven</string>
|
||||||
|
<string name="alarm_sat_short">Sam</string>
|
||||||
|
<string name="alarm_smart_wakeup">réveil intelligent</string>
|
||||||
|
<string name="user_feedback_miband_set_alarms_failed">Il y avais une erreur lors du paramétrage des alarmes, s\'il vous plaît essayer à nouveau!</string>
|
||||||
|
<string name="user_feedback_miband_set_alarms_ok">Alarmes envoyer à l\'appareil</string>
|
||||||
|
<string name="chart_no_data_synchronize">Aucune donnée. Synchroniser l\'appareil?</string>
|
||||||
|
<string name="user_feedback_miband_activity_data_transfer">A propos du transférer %1$s de données à partir de %2$s</string>
|
||||||
|
<string name="miband_prefs_fitness_goal">Objectif de pas par jour</string>
|
||||||
|
<string name="dbaccess_error_executing">Erreur d’exécution %1$s\'</string>
|
||||||
|
<string name="controlcenter_start_activitymonitor">Votre activité (ALPHA)</string>
|
||||||
|
<string name="cannot_connect">Impossible de se connecter: %1$s</string>
|
||||||
|
<string name="installer_activity_unable_to_find_handler">Impossible de trouver un gestionnaire pour installer ce fichier.</string>
|
||||||
|
<string name="pbw_install_handler_unable_to_install">Impossible d\'installer le fichier donné: $1%s</string>
|
||||||
|
<string name="pbw_install_handler_hw_revision_mismatch">Impossible d\'installer le firmware donnée: il ne correspond pas à la version du matériel de votre Pebble.</string>
|
||||||
|
<string name="installer_activity_wait_while_determining_status">S\'il vous plaît patienter pendant la détermination de l\'état de l\'installation ...</string>
|
||||||
|
</resources>
|
Loading…
Reference in New Issue
Block a user