diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiCoordinator.java index d16fe9c11..1155d7510 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiCoordinator.java @@ -367,6 +367,9 @@ public abstract class XiaomiCoordinator extends AbstractBLEDeviceCoordinator { // Other // settings.add(R.xml.devicesettings_header_other); + if (getContactsSlotCount(device) > 0) { + settings.add(R.xml.devicesettings_contacts); + } settings.add(R.xml.devicesettings_camera_remote); // diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/redmiwatch3active/RedmiWatch3ActiveCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/redmiwatch3active/RedmiWatch3ActiveCoordinator.java index b15bf069c..c0de7da34 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/redmiwatch3active/RedmiWatch3ActiveCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/redmiwatch3active/RedmiWatch3ActiveCoordinator.java @@ -27,6 +27,7 @@ import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiEncryptedCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiInstallHandler; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; public class RedmiWatch3ActiveCoordinator extends XiaomiEncryptedCoordinator { @Override @@ -65,4 +66,9 @@ public class RedmiWatch3ActiveCoordinator extends XiaomiEncryptedCoordinator { public boolean supportsMultipleWeatherLocations() { return true; } + + @Override + public int getContactsSlotCount(final GBDevice device) { + return 10; // TODO:verify + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiSupport.java index 51303c70c..3a1ceacac 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiSupport.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 José Rebelo +/* Copyright (C) 2023 José Rebelo, Andreas Shimokawa This file is part of Gadgetbridge. @@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -41,6 +42,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; +import nodomain.freeyourgadget.gadgetbridge.model.Contact; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; @@ -408,6 +410,11 @@ public abstract class XiaomiSupport extends AbstractBTLEDeviceSupport { weatherService.onSendWeather(weatherSpec); } + @Override + public void onSetContacts(ArrayList contacts) { + phonebookService.setContacts((List) contacts); + } + public XiaomiCoordinator getCoordinator() { return (XiaomiCoordinator) gbDevice.getDeviceCoordinator(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiPhonebookService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiPhonebookService.java index c198d60e0..d6be412d7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiPhonebookService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiPhonebookService.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 Yoran Vulker +/* Copyright (C) 2023 Yoran Vulker, Andreas Shimokawa This file is part of Gadgetbridge. @@ -25,10 +25,15 @@ import android.text.TextUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.nio.charset.StandardCharsets; +import java.util.List; + import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.model.Contact; import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto; import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public class XiaomiPhonebookService extends AbstractXiaomiService { @@ -37,6 +42,7 @@ public class XiaomiPhonebookService extends AbstractXiaomiService { private static final int CMD_GET_CONTACT = 2; private static final int CMD_GET_CONTACT_RESPONSE = 3; + private static final int CMD_SET_CONTACT_LIST = 5; public XiaomiPhonebookService(final XiaomiSupport support) { super(support); @@ -133,4 +139,26 @@ public class XiaomiPhonebookService extends AbstractXiaomiService { contactInfoBuilder.setDisplayName(name); return contactInfoBuilder.build(); } + + public void setContacts(List contacts) { + final XiaomiProto.ContactList.Builder contactList = XiaomiProto.ContactList.newBuilder(); + int maxContacts = 10; // TODO:verify, do not copy and paste + int numContacts = Math.min(contacts.size(), maxContacts); + + for (int i = 0; i < numContacts; i++) { + final Contact contact = contacts.get(i); + if (!StringUtils.isNullOrEmpty(contact.getName()) && !StringUtils.isNullOrEmpty(contact.getNumber())) { + contactList.addContactInfo(XiaomiProto.ContactInfo.newBuilder().setDisplayName(contact.getName()).setPhoneNumber(contact.getNumber())); + } + } + + getSupport().sendCommand( + "send contact list", + XiaomiProto.Command.newBuilder() + .setType(COMMAND_TYPE) + .setSubtype(CMD_SET_CONTACT_LIST) + .setPhonebook(XiaomiProto.Phonebook.newBuilder().setContactList(contactList)) + .build() + ); + } } diff --git a/app/src/main/proto/xiaomi.proto b/app/src/main/proto/xiaomi.proto index aa5f19f67..2c7cde082 100644 --- a/app/src/main/proto/xiaomi.proto +++ b/app/src/main/proto/xiaomi.proto @@ -882,7 +882,13 @@ message ContactInfo { optional string phoneNumber = 2; } +message ContactList { + repeated ContactInfo contactInfo = 1; + optional string phoneNumber = 2; +} + message Phonebook { optional string requestedPhoneNumber = 2; optional ContactInfo contactInfo = 3; + optional ContactList contactList = 4; }