From 1f083041b942e9275165a0dac2bbb4425a42a7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Paulo=20Barraca?= Date: Tue, 24 Jan 2017 01:44:30 +0000 Subject: [PATCH 1/2] HPlus: Improve display of new messages and phone calls --- .../devices/hplus/HPlusConstants.java | 59 +++++++++ .../service/devices/hplus/HPlusSupport.java | 112 +++++++++++------- .../gadgetbridge/util/StringUtils.java | 25 ++++ 3 files changed, 156 insertions(+), 40 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java index 5feaf6d7..01e619bf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java @@ -4,6 +4,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.hplus; * @author João Paulo Barraca <jpbarraca@gmail.com> */ +import java.util.HashMap; +import java.util.Map; import java.util.UUID; public final class HPlusConstants { @@ -110,4 +112,61 @@ public final class HPlusConstants { public static final String PREF_HPLUS_SIT_START_TIME = "hplus_sit_start_time"; public static final String PREF_HPLUS_SIT_END_TIME = "hplus_sit_end_time"; public static final String PREF_HPLUS_COUNTRY = "hplus_country"; + + public static final Map transliterateMap = new HashMap(){ + { + //These are missing + put('ó', new Byte((byte) 111)); + put('Ó', new Byte((byte) 79)); + put('í', new Byte((byte) 105)); + put('Í', new Byte((byte) 73)); + put('ú', new Byte((byte) 117)); + put('Ú', new Byte((byte) 85)); + + //These mostly belong to the extended ASCII table + put('Ç', new Byte((byte) 128)); + put('ü', new Byte((byte) 129)); + put('é', new Byte((byte) 130)); + put('â', new Byte((byte) 131)); + put('ä', new Byte((byte) 132)); + put('à', new Byte((byte) 133)); + put('ã', new Byte((byte) 134)); + put('ç', new Byte((byte) 135)); + put('ê', new Byte((byte) 136)); + put('ë', new Byte((byte) 137)); + put('è', new Byte((byte) 138)); + put('Ï', new Byte((byte) 139)); + put('Î', new Byte((byte) 140)); + put('Ì', new Byte((byte) 141)); + put('Ã', new Byte((byte) 142)); + put('Ä', new Byte((byte) 143)); + put('É', new Byte((byte) 144)); + put('æ', new Byte((byte) 145)); + put('Æ', new Byte((byte) 146)); + put('ô', new Byte((byte) 147)); + put('ö', new Byte((byte) 148)); + put('ò', new Byte((byte) 149)); + put('û', new Byte((byte) 150)); + put('ù', new Byte((byte) 151)); + put('ÿ', new Byte((byte) 152)); + put('Ö', new Byte((byte) 153)); + put('Ü', new Byte((byte) 154)); + put('¢', new Byte((byte) 155)); + put('£', new Byte((byte) 156)); + put('¥', new Byte((byte) 157)); + put('ƒ', new Byte((byte) 159)); + put('á', new Byte((byte) 160)); + put('ñ', new Byte((byte) 164)); + put('Ñ', new Byte((byte) 165)); + put('ª', new Byte((byte) 166)); + put('º', new Byte((byte) 167)); + put('¿', new Byte((byte) 168)); + put('¬', new Byte((byte) 170)); + put('½', new Byte((byte) 171)); + put('¼', new Byte((byte) 172)); + put('¡', new Byte((byte) 173)); + put('«', new Byte((byte) 174)); + put('»', new Byte((byte) 175)); + } + }; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 73072c51..076a0296 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -14,13 +14,16 @@ import android.net.Uri; import android.support.v4.content.LocalBroadcastManager; import android.widget.Toast; +import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; +import java.util.List; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants; @@ -41,6 +44,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateA import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public class HPlusSupport extends AbstractBTLEDeviceSupport { @@ -644,7 +649,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { private void showIncomingCall(String name, String number) { try { - TransactionBuilder builder = performInitialized("incomingCallIcon"); + TransactionBuilder builder = performInitialized("incomingCall"); //Enable call notifications builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_ACTION_INCOMING_CALL, 1}); @@ -652,13 +657,8 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { //Show Call Icon builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_CALL, HPlusConstants.ARG_INCOMING_CALL}); - builder.queue(getQueue()); - byte[] msg = new byte[13]; - builder = performInitialized("incomingCallNumber"); - builder.wait(200); - //Show call number for (int i = 0; i < msg.length; i++) msg[i] = ' '; @@ -666,28 +666,28 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { for (int i = 0; i < number.length() && i < (msg.length - 1); i++) msg[i + 1] = (byte) number.charAt(i); - msg[0] = HPlusConstants.CMD_SET_INCOMING_CALL_NUMBER; builder.write(ctrlCharacteristic, msg); - builder.queue(getQueue()); - - builder = performInitialized("incomingCallText"); builder.wait(200); + msg = msg.clone(); //Show call name - //Must call twice, otherwise nothing happens + for (int i = 0; i < msg.length; i++) msg[i] = ' '; - for (int i = 0; i < name.length() && i < (msg.length - 1); i++) - msg[i + 1] = (byte) name.charAt(i); + if(LanguageUtils.transliterate()) { + name = LanguageUtils.transliterate(name); + } + + byte[] nameBytes = encodeStringToDevice(name); + for (int i = 0; i < nameBytes.length && i < (msg.length - 1); i++) + msg[i + 1] = nameBytes[i]; msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT_NAME; builder.write(ctrlCharacteristic, msg); - builder.wait(200); - msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT_NAME_CN; builder.write(ctrlCharacteristic, msg); @@ -703,45 +703,44 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { try { TransactionBuilder builder = performInitialized("notification"); - byte[] msg = new byte[20]; - for (int i = 0; i < msg.length; i++) - msg[i] = ' '; - - msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT; - String message = ""; - //TODO: Create StringUtils.pad and StringUtils.truncate - if (title != null) { - if (title.length() > 17) { - message = title.substring(0, 17); - } else { - message = title; - for (int i = message.length(); i < 17; i++) - message += " "; + if (title != null && title.length() > 0) { + + if(LanguageUtils.transliterate()){ + title = LanguageUtils.transliterate(title); } + message = StringUtils.pad(StringUtils.truncate(title, 16), 16); //Limit title to top row } - message += body; - int length = message.length() / 17; + if(body != null) { + if(LanguageUtils.transliterate()){ + body = LanguageUtils.transliterate(body); + } - builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_ACTION_INCOMING_SOCIAL, (byte) 255}); + message += body; + } + + byte[] messageBytes = encodeStringToDevice(message); + + int length = messageBytes.length / 17; builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_MESSAGE, HPlusConstants.ARG_INCOMING_MESSAGE}); - int remaining; - - if (message.length() % 17 > 0) - remaining = length + 1; - else - remaining = length; + int remaining = Math.min(255, (messageBytes.length % 17 > 0) ? length + 1 : length); + byte[] msg = new byte[20]; + msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT; msg[1] = (byte) remaining; + + for (int i = 2; i < msg.length; i++) + msg[i] = ' '; + int message_index = 0; int i = 3; - for (int j = 0; j < message.length(); j++) { - msg[i++] = (byte) message.charAt(j); + for (int j = 0; j < messageBytes.length; j++) { + msg[i++] = messageBytes[j]; if (i == msg.length) { message_index++; @@ -776,6 +775,39 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } } + /** + * HPlus devices accept a subset of GB2312 with some modifications. + * This function will apply a custom transliteration. + * While related to the methods implemented in LanguageUtils. These are specific for HPLUS + * + * @param s The String to transliterate + * @return An array of bytes ready to be sent to the device + */ + private byte[] encodeStringToDevice(String s){ + + List outBytes = new ArrayList(); + + for(int i = 0; i < s.length(); i++){ + Character c = s.charAt(i); + byte[] cs; + + if(HPlusConstants.transliterateMap.containsKey(c)){ + cs = new byte[] {HPlusConstants.transliterateMap.get(c)}; + }else { + try { + cs = c.toString().getBytes("GB2312"); + } catch (UnsupportedEncodingException e) { + //Fallback. Result string may be strange, but better than nothing + cs = c.toString().getBytes(); + } + } + for(int j = 0; j < cs.length; j++) + outBytes.add(cs[j]); + } + + return ArrayUtils.toPrimitive(outBytes.toArray(new Byte[outBytes.size()])); + } + @Override public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java new file mode 100644 index 00000000..8dd6d8cc --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java @@ -0,0 +1,25 @@ +package nodomain.freeyourgadget.gadgetbridge.util; + +public class StringUtils { + + public static String truncate(String s, int maxLength){ + int length = Math.min(s.length(), maxLength); + + if(length < 0) + return ""; + + return s.substring(0, length); + } + + public static String pad(String s, int length){ + return pad(s, length, ' '); + } + + public static String pad(String s, int length, char padChar){ + + while(s.length() < length) + s += padChar; + + return s; + } +} From b4a4b3916a6e785bb58b10e9ef25b12d8104ac96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Paulo=20Barraca?= Date: Tue, 24 Jan 2017 10:39:24 +0000 Subject: [PATCH 2/2] HPlus: Remove LanguageUtils transliterate from HPlusSupport --- .../service/devices/hplus/HPlusSupport.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 076a0296..c410537c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -44,7 +44,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateA import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; import nodomain.freeyourgadget.gadgetbridge.util.GB; -import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; @@ -677,10 +676,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { for (int i = 0; i < msg.length; i++) msg[i] = ' '; - if(LanguageUtils.transliterate()) { - name = LanguageUtils.transliterate(name); - } - byte[] nameBytes = encodeStringToDevice(name); for (int i = 0; i < nameBytes.length && i < (msg.length - 1); i++) msg[i + 1] = nameBytes[i]; @@ -706,18 +701,10 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { String message = ""; if (title != null && title.length() > 0) { - - if(LanguageUtils.transliterate()){ - title = LanguageUtils.transliterate(title); - } message = StringUtils.pad(StringUtils.truncate(title, 16), 16); //Limit title to top row } if(body != null) { - if(LanguageUtils.transliterate()){ - body = LanguageUtils.transliterate(body); - } - message += body; }