mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-26 16:41:43 +01:00
Merge pull request #517 from jpbarraca/hplus-fix-3
HPlus: Improve display of new messages and phone calls
This commit is contained in:
commit
3dd058cf81
@ -4,6 +4,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
|||||||
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public final class HPlusConstants {
|
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_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_SIT_END_TIME = "hplus_sit_end_time";
|
||||||
public static final String PREF_HPLUS_COUNTRY = "hplus_country";
|
public static final String PREF_HPLUS_COUNTRY = "hplus_country";
|
||||||
|
|
||||||
|
public static final Map<Character, Byte> transliterateMap = new HashMap<Character, Byte>(){
|
||||||
|
{
|
||||||
|
//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));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,16 @@ import android.net.Uri;
|
|||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants;
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants;
|
||||||
@ -41,6 +44,7 @@ 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.DeviceInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
||||||
@ -644,7 +648,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
private void showIncomingCall(String name, String number) {
|
private void showIncomingCall(String name, String number) {
|
||||||
try {
|
try {
|
||||||
TransactionBuilder builder = performInitialized("incomingCallIcon");
|
TransactionBuilder builder = performInitialized("incomingCall");
|
||||||
|
|
||||||
//Enable call notifications
|
//Enable call notifications
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_ACTION_INCOMING_CALL, 1});
|
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_ACTION_INCOMING_CALL, 1});
|
||||||
@ -652,13 +656,8 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
//Show Call Icon
|
//Show Call Icon
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_CALL, HPlusConstants.ARG_INCOMING_CALL});
|
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_CALL, HPlusConstants.ARG_INCOMING_CALL});
|
||||||
|
|
||||||
builder.queue(getQueue());
|
|
||||||
|
|
||||||
byte[] msg = new byte[13];
|
byte[] msg = new byte[13];
|
||||||
|
|
||||||
builder = performInitialized("incomingCallNumber");
|
|
||||||
builder.wait(200);
|
|
||||||
|
|
||||||
//Show call number
|
//Show call number
|
||||||
for (int i = 0; i < msg.length; i++)
|
for (int i = 0; i < msg.length; i++)
|
||||||
msg[i] = ' ';
|
msg[i] = ' ';
|
||||||
@ -666,28 +665,24 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
for (int i = 0; i < number.length() && i < (msg.length - 1); i++)
|
for (int i = 0; i < number.length() && i < (msg.length - 1); i++)
|
||||||
msg[i + 1] = (byte) number.charAt(i);
|
msg[i + 1] = (byte) number.charAt(i);
|
||||||
|
|
||||||
|
|
||||||
msg[0] = HPlusConstants.CMD_SET_INCOMING_CALL_NUMBER;
|
msg[0] = HPlusConstants.CMD_SET_INCOMING_CALL_NUMBER;
|
||||||
|
|
||||||
builder.write(ctrlCharacteristic, msg);
|
builder.write(ctrlCharacteristic, msg);
|
||||||
builder.queue(getQueue());
|
|
||||||
|
|
||||||
builder = performInitialized("incomingCallText");
|
|
||||||
builder.wait(200);
|
builder.wait(200);
|
||||||
|
msg = msg.clone();
|
||||||
|
|
||||||
//Show call name
|
//Show call name
|
||||||
//Must call twice, otherwise nothing happens
|
|
||||||
for (int i = 0; i < msg.length; i++)
|
for (int i = 0; i < msg.length; i++)
|
||||||
msg[i] = ' ';
|
msg[i] = ' ';
|
||||||
|
|
||||||
for (int i = 0; i < name.length() && i < (msg.length - 1); i++)
|
byte[] nameBytes = encodeStringToDevice(name);
|
||||||
msg[i + 1] = (byte) name.charAt(i);
|
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;
|
msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT_NAME;
|
||||||
builder.write(ctrlCharacteristic, msg);
|
builder.write(ctrlCharacteristic, msg);
|
||||||
|
|
||||||
builder.wait(200);
|
|
||||||
|
|
||||||
msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT_NAME_CN;
|
msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT_NAME_CN;
|
||||||
builder.write(ctrlCharacteristic, msg);
|
builder.write(ctrlCharacteristic, msg);
|
||||||
|
|
||||||
@ -703,45 +698,36 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
try {
|
try {
|
||||||
TransactionBuilder builder = performInitialized("notification");
|
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 = "";
|
String message = "";
|
||||||
|
|
||||||
//TODO: Create StringUtils.pad and StringUtils.truncate
|
if (title != null && title.length() > 0) {
|
||||||
if (title != null) {
|
message = StringUtils.pad(StringUtils.truncate(title, 16), 16); //Limit title to top row
|
||||||
if (title.length() > 17) {
|
|
||||||
message = title.substring(0, 17);
|
|
||||||
} else {
|
|
||||||
message = title;
|
|
||||||
for (int i = message.length(); i < 17; i++)
|
|
||||||
message += " ";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(body != null) {
|
||||||
message += body;
|
message += body;
|
||||||
|
}
|
||||||
|
|
||||||
int length = message.length() / 17;
|
byte[] messageBytes = encodeStringToDevice(message);
|
||||||
|
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_ACTION_INCOMING_SOCIAL, (byte) 255});
|
int length = messageBytes.length / 17;
|
||||||
|
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_MESSAGE, HPlusConstants.ARG_INCOMING_MESSAGE});
|
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_MESSAGE, HPlusConstants.ARG_INCOMING_MESSAGE});
|
||||||
|
|
||||||
int remaining;
|
int remaining = Math.min(255, (messageBytes.length % 17 > 0) ? length + 1 : length);
|
||||||
|
|
||||||
if (message.length() % 17 > 0)
|
|
||||||
remaining = length + 1;
|
|
||||||
else
|
|
||||||
remaining = length;
|
|
||||||
|
|
||||||
|
byte[] msg = new byte[20];
|
||||||
|
msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT;
|
||||||
msg[1] = (byte) remaining;
|
msg[1] = (byte) remaining;
|
||||||
|
|
||||||
|
for (int i = 2; i < msg.length; i++)
|
||||||
|
msg[i] = ' ';
|
||||||
|
|
||||||
int message_index = 0;
|
int message_index = 0;
|
||||||
int i = 3;
|
int i = 3;
|
||||||
|
|
||||||
for (int j = 0; j < message.length(); j++) {
|
for (int j = 0; j < messageBytes.length; j++) {
|
||||||
msg[i++] = (byte) message.charAt(j);
|
msg[i++] = messageBytes[j];
|
||||||
|
|
||||||
if (i == msg.length) {
|
if (i == msg.length) {
|
||||||
message_index++;
|
message_index++;
|
||||||
@ -776,6 +762,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<Byte> outBytes = new ArrayList<Byte>();
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public boolean onCharacteristicChanged(BluetoothGatt gatt,
|
public boolean onCharacteristicChanged(BluetoothGatt gatt,
|
||||||
BluetoothGattCharacteristic characteristic) {
|
BluetoothGattCharacteristic characteristic) {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user