mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-08-25 00:30:37 +02:00
WIP: Work towards SMS replies / canned replies
- Implement the PebbleProtocol side (2.x and 3.x) - Add Preferences for canned replies This can be tested by enabling untested features in Pebble Settings It lets you see and select the replies set up in "Canned Repies" on the Pebble You will get a "NOT IMPLENTED" message on your Pebble. THIS DOES NOT ACTUALLY DO ANYTHING USEFUL YET.
This commit is contained in:
parent
f258e62633
commit
53fb63781e
@ -76,7 +76,7 @@ public class DebugActivity extends Activity {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
NotificationSpec notificationSpec = new NotificationSpec();
|
||||
notificationSpec.sender = getResources().getText(R.string.app_name).toString();
|
||||
notificationSpec.phoneNumber = getResources().getText(R.string.app_name).toString();
|
||||
notificationSpec.body = editContent.getText().toString();
|
||||
notificationSpec.type = NotificationType.SMS;
|
||||
notificationSpec.id = -1;
|
||||
|
@ -50,8 +50,8 @@ public class SettingsActivity extends AbstractSettingsActivity {
|
||||
}
|
||||
});
|
||||
|
||||
final Preference pebbleEmuAddr = findPreference("pebble_emu_addr");
|
||||
pebbleEmuAddr.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
pref = findPreference("pebble_emu_addr");
|
||||
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
Intent refreshIntent = new Intent(ControlCenter.ACTION_REFRESH_DEVICELIST);
|
||||
@ -62,8 +62,8 @@ public class SettingsActivity extends AbstractSettingsActivity {
|
||||
|
||||
});
|
||||
|
||||
final Preference pebbleEmuPort = findPreference("pebble_emu_port");
|
||||
pebbleEmuPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
pref = findPreference("pebble_emu_port");
|
||||
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
Intent refreshIntent = new Intent(ControlCenter.ACTION_REFRESH_DEVICELIST);
|
||||
@ -110,6 +110,14 @@ public class SettingsActivity extends AbstractSettingsActivity {
|
||||
"pebble_emu_addr",
|
||||
"pebble_emu_port",
|
||||
"pebble_reconnect_attempts",
|
||||
"canned_reply_1",
|
||||
"canned_reply_2",
|
||||
"canned_reply_3",
|
||||
"canned_reply_4",
|
||||
"canned_reply_5",
|
||||
"canned_reply_6",
|
||||
"canned_reply_7",
|
||||
"canned_reply_8",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ import android.os.PowerManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.telephony.SmsMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||
|
@ -9,4 +9,5 @@ public class NotificationSpec {
|
||||
public String body;
|
||||
public NotificationType type;
|
||||
public String sourceName;
|
||||
public String[] cannedReplies;
|
||||
}
|
||||
|
@ -217,6 +217,21 @@ public class DeviceCommunicationService extends Service {
|
||||
notificationSpec.sourceName = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCENAME);
|
||||
if (notificationSpec.type == NotificationType.SMS && notificationSpec.phoneNumber != null) {
|
||||
notificationSpec.sender = getContactDisplayNameByNumber(notificationSpec.phoneNumber);
|
||||
|
||||
// NOTE: maybe not where it belongs
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
if (sharedPrefs.getBoolean("pebble_force_untested", false)) {
|
||||
// I would rather like to save that as an array in ShadredPreferences
|
||||
// this would work but I dont know how to do the same in the Settings Activity's xml
|
||||
ArrayList<String> replies = new ArrayList<>();
|
||||
for (int i = 1; i <= 8; i++) {
|
||||
String reply = sharedPrefs.getString("canned_reply_" + i, null);
|
||||
if (reply != null && !reply.equals("")) {
|
||||
replies.add(reply);
|
||||
}
|
||||
}
|
||||
notificationSpec.cannedReplies = replies.toArray(new String[replies.size()]);
|
||||
}
|
||||
}
|
||||
mDeviceSupport.onNotification(notificationSpec);
|
||||
break;
|
||||
|
@ -421,10 +421,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
if (isFw3x) {
|
||||
// 3.x notification
|
||||
//return encodeTimelinePin(id, (int) ((ts + 600) & 0xffffffffL), (short) 90, PebbleIconID.TIMELINE_CALENDAR, title); // really, this is just for testing
|
||||
return encodeBlobdbNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, notificationSpec.sourceName, hasHandle, notificationSpec.type);
|
||||
return encodeBlobdbNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, notificationSpec.sourceName, hasHandle, notificationSpec.type, notificationSpec.cannedReplies);
|
||||
} else if (mForceProtocol || notificationSpec.type != NotificationType.EMAIL) {
|
||||
// 2.x notification
|
||||
return encodeExtensibleNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, notificationSpec.sourceName, hasHandle);
|
||||
return encodeExtensibleNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, notificationSpec.sourceName, hasHandle, notificationSpec.cannedReplies);
|
||||
} else {
|
||||
// 1.x notification on FW 2.X
|
||||
String[] parts = {title, notificationSpec.body, ts.toString(), subtitle};
|
||||
@ -467,7 +467,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
return encodeSetCallState("Where are you?", "Gadgetbridge", start ? ServiceCommand.CALL_INCOMING : ServiceCommand.CALL_END);
|
||||
}
|
||||
|
||||
private static byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle) {
|
||||
private static byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, String[] cannedReplies) {
|
||||
final short ACTION_LENGTH_MIN = 10;
|
||||
|
||||
String[] parts = {title, subtitle, body};
|
||||
@ -478,6 +478,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
String dismiss_string;
|
||||
String open_string = "Open on phone";
|
||||
String mute_string = "Mute";
|
||||
String reply_string = "Reply";
|
||||
if (sourceName != null) {
|
||||
mute_string += " " + sourceName;
|
||||
}
|
||||
@ -496,6 +497,15 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.getBytes().length);
|
||||
}
|
||||
|
||||
int replies_length = -1;
|
||||
if (cannedReplies != null) {
|
||||
actions_count++;
|
||||
for (String reply : cannedReplies) {
|
||||
replies_length += reply.getBytes().length + 1;
|
||||
}
|
||||
actions_length += ACTION_LENGTH_MIN + reply_string.getBytes().length + replies_length + 3; // 3 = attribute id (byte) + length(short)
|
||||
}
|
||||
|
||||
byte attributes_count = 0;
|
||||
|
||||
int length = 21 + 10 + actions_length;
|
||||
@ -554,7 +564,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
buf.putShort((short) dismiss_string.getBytes().length);
|
||||
buf.put(dismiss_string.getBytes());
|
||||
|
||||
// open action
|
||||
// open and mute actions
|
||||
if (hasHandle) {
|
||||
buf.put((byte) 0x01);
|
||||
buf.put((byte) 0x02); // generic
|
||||
@ -572,6 +582,23 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
|
||||
}
|
||||
|
||||
if (cannedReplies != null) {
|
||||
buf.put((byte) 0x05);
|
||||
buf.put((byte) 0x03); // reply action
|
||||
buf.put((byte) 0x02); // number attributes
|
||||
buf.put((byte) 0x01); // title
|
||||
buf.putShort((short) reply_string.getBytes().length);
|
||||
buf.put(reply_string.getBytes());
|
||||
buf.put((byte) 0x08); // canned replies
|
||||
buf.putShort((short) replies_length);
|
||||
for (int i = 0; i < cannedReplies.length - 1; i++) {
|
||||
buf.put(cannedReplies[i].getBytes());
|
||||
buf.put((byte) 0x00);
|
||||
}
|
||||
// last one must not be zero terminated, else we get an additional emply reply
|
||||
buf.put(cannedReplies[cannedReplies.length - 1].getBytes());
|
||||
}
|
||||
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
@ -645,7 +672,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
return encodeBlobdb(uuid, BLOBDB_INSERT, BLOBDB_PIN, buf.array());
|
||||
}
|
||||
|
||||
private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, NotificationType notificationType) {
|
||||
private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, NotificationType notificationType, String[] cannedReplies) {
|
||||
final short NOTIFICATION_PIN_LENGTH = 46;
|
||||
final short ACTION_LENGTH_MIN = 10;
|
||||
|
||||
@ -697,6 +724,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
String dismiss_string;
|
||||
String open_string = "Open on phone";
|
||||
String mute_string = "Mute";
|
||||
String reply_string = "Reply";
|
||||
if (sourceName != null) {
|
||||
mute_string += " " + sourceName;
|
||||
}
|
||||
@ -714,6 +742,15 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.getBytes().length);
|
||||
}
|
||||
|
||||
int replies_length = -1;
|
||||
if (cannedReplies != null) {
|
||||
actions_count++;
|
||||
for (String reply : cannedReplies) {
|
||||
replies_length += reply.getBytes().length + 1;
|
||||
}
|
||||
actions_length += ACTION_LENGTH_MIN + reply_string.getBytes().length + replies_length + 3; // 3 = attribute id (byte) + length(short)
|
||||
}
|
||||
|
||||
byte attributes_count = 2; // icon
|
||||
short attributes_length = (short) (11 + actions_length);
|
||||
if (parts != null) {
|
||||
@ -798,6 +835,24 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
buf.putShort((short) mute_string.getBytes().length);
|
||||
buf.put(mute_string.getBytes());
|
||||
}
|
||||
|
||||
if (cannedReplies != null) {
|
||||
buf.put((byte) 0x05);
|
||||
buf.put((byte) 0x03); // reply action
|
||||
buf.put((byte) 0x02); // number attributes
|
||||
buf.put((byte) 0x01); // title
|
||||
buf.putShort((short) reply_string.getBytes().length);
|
||||
buf.put(reply_string.getBytes());
|
||||
buf.put((byte) 0x08); // canned replies
|
||||
buf.putShort((short) replies_length);
|
||||
for (int i = 0; i < cannedReplies.length - 1; i++) {
|
||||
buf.put(cannedReplies[i].getBytes());
|
||||
buf.put((byte) 0x00);
|
||||
}
|
||||
// last one must not be zero terminated, else we get an additional emply reply
|
||||
buf.put(cannedReplies[cannedReplies.length - 1].getBytes());
|
||||
}
|
||||
|
||||
return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array());
|
||||
}
|
||||
|
||||
@ -1436,7 +1491,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
if (command == 0x02) {
|
||||
int id = buf.getInt();
|
||||
byte action = buf.get();
|
||||
if (action >= 0x01 && action <= 0x04) {
|
||||
if (action >= 0x01 && action <= 0x05) {
|
||||
GBDeviceEventNotificationControl devEvtNotificationControl = new GBDeviceEventNotificationControl();
|
||||
devEvtNotificationControl.handle = id;
|
||||
GBDeviceEventSendBytes sendBytesAck = null;
|
||||
@ -1458,6 +1513,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
sendBytesAck = new GBDeviceEventSendBytes();
|
||||
sendBytesAck.encodedBytes = encodeActionResponse2x(id, action, 6, "Muted");
|
||||
break;
|
||||
case 0x05:
|
||||
devEvtNotificationControl = null; // not implemented
|
||||
sendBytesAck = new GBDeviceEventSendBytes();
|
||||
sendBytesAck.encodedBytes = encodeActionResponse2x(id, action, 6, "NOT IMPLEMENTED");
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -1479,7 +1539,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
long uuid_low = buf.getLong();
|
||||
int id = (int) (uuid_low & 0xffffffffL);
|
||||
byte action = buf.get();
|
||||
if (action >= 0x01 && action <= 0x04) {
|
||||
if (action >= 0x01 && action <= 0x05) {
|
||||
GBDeviceEventNotificationControl dismissNotification = new GBDeviceEventNotificationControl();
|
||||
dismissNotification.handle = id;
|
||||
String caption = "undefined";
|
||||
@ -1505,6 +1565,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
caption = "Muted";
|
||||
icon_id = PebbleIconID.RESULT_MUTE;
|
||||
break;
|
||||
case 0x05:
|
||||
dismissNotification = null; // not implemented
|
||||
caption = "NOT IMPLEMENTED";
|
||||
icon_id = PebbleIconID.GENERIC_WARNING;
|
||||
break;
|
||||
}
|
||||
GBDeviceEventSendBytes sendBytesAck = new GBDeviceEventSendBytes();
|
||||
sendBytesAck.encodedBytes = encodeActionResponse(new UUID(uuid_high, uuid_low), icon_id, caption);
|
||||
|
@ -55,6 +55,8 @@
|
||||
|
||||
<string name="pref_blacklist">Blacklist Apps</string>
|
||||
|
||||
<string name="pref_title_canned_replies">Canned Replies</string>
|
||||
|
||||
<string name="pref_header_development">Developer Options</string>
|
||||
<string name="pref_title_development_miaddr">Mi Band address</string>
|
||||
|
||||
|
@ -65,6 +65,35 @@
|
||||
<Preference
|
||||
android:key="pref_key_blacklist"
|
||||
android:title="@string/pref_blacklist" />
|
||||
<PreferenceScreen
|
||||
android:key="pref_key_canned_replies"
|
||||
android:title="@string/pref_title_canned_replies"
|
||||
android:dependency="pebble_force_untested" >
|
||||
<EditTextPreference
|
||||
android:key="canned_reply_1"
|
||||
android:maxLength="64" />
|
||||
<EditTextPreference
|
||||
android:key="canned_reply_2"
|
||||
android:maxLength="64" />
|
||||
<EditTextPreference
|
||||
android:key="canned_reply_3"
|
||||
android:maxLength="64" />
|
||||
<EditTextPreference
|
||||
android:key="canned_reply_4"
|
||||
android:maxLength="64" />
|
||||
<EditTextPreference
|
||||
android:key="canned_reply_5"
|
||||
android:maxLength="64" />
|
||||
<EditTextPreference
|
||||
android:key="canned_reply_6"
|
||||
android:maxLength="64" />
|
||||
<EditTextPreference
|
||||
android:key="canned_reply_7"
|
||||
android:maxLength="64" />
|
||||
<EditTextPreference
|
||||
android:key="canned_reply_8"
|
||||
android:maxLength="64" />
|
||||
</PreferenceScreen>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
Loading…
Reference in New Issue
Block a user