mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-02 13:07:34 +01:00
Pebble: Allow muting (blacklisting) Apps from within generic notifications on the watch
Closes #113
This commit is contained in:
parent
94ad7f2eb9
commit
e3533a2b18
@ -1,6 +1,7 @@
|
|||||||
###Changelog
|
###Changelog
|
||||||
|
|
||||||
####Next Version
|
####Next Version
|
||||||
|
* Pebble: Allow muting (blacklisting) Apps from within generic notifications on the watch
|
||||||
* Pebble: Detect all known Pebble Versions including new "chalk" platform (Pebble Time Round)
|
* Pebble: Detect all known Pebble Versions including new "chalk" platform (Pebble Time Round)
|
||||||
* Option to ignore phone calls (useful for Pebble Dialer)
|
* Option to ignore phone calls (useful for Pebble Dialer)
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
@ -31,6 +32,7 @@ public class GBApplication extends Application {
|
|||||||
private static ActivityDatabaseHandler mActivityDatabaseHandler;
|
private static ActivityDatabaseHandler mActivityDatabaseHandler;
|
||||||
private static final Lock dbLock = new ReentrantLock();
|
private static final Lock dbLock = new ReentrantLock();
|
||||||
private static DeviceService deviceService;
|
private static DeviceService deviceService;
|
||||||
|
private static SharedPreferences sharedPrefs;
|
||||||
|
|
||||||
public GBApplication() {
|
public GBApplication() {
|
||||||
context = this;
|
context = this;
|
||||||
@ -46,6 +48,8 @@ public class GBApplication extends Application {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
|
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
// don't do anything here before we set up logging, otherwise
|
// don't do anything here before we set up logging, otherwise
|
||||||
// slf4j may be implicitly initialized before we properly configured it.
|
// slf4j may be implicitly initialized before we properly configured it.
|
||||||
setupLogging();
|
setupLogging();
|
||||||
@ -57,14 +61,14 @@ public class GBApplication extends Application {
|
|||||||
|
|
||||||
GB.environment = GBEnvironment.createDeviceEnvironment();
|
GB.environment = GBEnvironment.createDeviceEnvironment();
|
||||||
mActivityDatabaseHandler = new ActivityDatabaseHandler(context);
|
mActivityDatabaseHandler = new ActivityDatabaseHandler(context);
|
||||||
|
loadBlackList();
|
||||||
// for testing DB stuff
|
// for testing DB stuff
|
||||||
// SQLiteDatabase db = mActivityDatabaseHandler.getWritableDatabase();
|
// SQLiteDatabase db = mActivityDatabaseHandler.getWritableDatabase();
|
||||||
// db.close();
|
// db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFileLoggingEnabled() {
|
public static boolean isFileLoggingEnabled() {
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(GBApplication.getContext());
|
return sharedPrefs.getBoolean("log_to_file", false);
|
||||||
return prefs.getBoolean("log_to_file", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupLogging() {
|
private void setupLogging() {
|
||||||
@ -130,4 +134,36 @@ public class GBApplication extends Application {
|
|||||||
public static boolean isRunningLollipopOrLater() {
|
public static boolean isRunningLollipopOrLater() {
|
||||||
return VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
return VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HashSet<String> blacklist = null;
|
||||||
|
|
||||||
|
public static void loadBlackList() {
|
||||||
|
blacklist = (HashSet<String>) sharedPrefs.getStringSet("package_blacklist", null);
|
||||||
|
if (blacklist == null) {
|
||||||
|
blacklist = new HashSet<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveBlackList() {
|
||||||
|
SharedPreferences.Editor editor = sharedPrefs.edit();
|
||||||
|
if (blacklist.isEmpty()) {
|
||||||
|
editor.putStringSet("package_blacklist", null);
|
||||||
|
} else {
|
||||||
|
editor.putStringSet("package_blacklist", blacklist);
|
||||||
|
}
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addToBlacklist(String packageName) {
|
||||||
|
if (!blacklist.contains(packageName)) {
|
||||||
|
blacklist.add(packageName);
|
||||||
|
saveBlackList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void removeFromBlacklist(String packageName) {
|
||||||
|
blacklist.remove(packageName);
|
||||||
|
saveBlackList();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,9 @@ import android.widget.TextView;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
|
||||||
|
|
||||||
@ -47,37 +47,6 @@ public class AppBlacklistActivity extends Activity {
|
|||||||
|
|
||||||
private SharedPreferences sharedPrefs;
|
private SharedPreferences sharedPrefs;
|
||||||
|
|
||||||
private HashSet<String> blacklist = null;
|
|
||||||
|
|
||||||
private void loadBlackList() {
|
|
||||||
blacklist = (HashSet<String>) sharedPrefs.getStringSet("package_blacklist", null);
|
|
||||||
if (blacklist == null) {
|
|
||||||
blacklist = new HashSet<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveBlackList() {
|
|
||||||
SharedPreferences.Editor editor = sharedPrefs.edit();
|
|
||||||
if (blacklist.isEmpty()) {
|
|
||||||
editor.putStringSet("package_blacklist", null);
|
|
||||||
} else {
|
|
||||||
editor.putStringSet("package_blacklist", blacklist);
|
|
||||||
}
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void addToBlacklist(String packageName) {
|
|
||||||
if (!blacklist.contains(packageName)) {
|
|
||||||
blacklist.add(packageName);
|
|
||||||
saveBlackList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void removeFromBlacklist(String packageName) {
|
|
||||||
blacklist.remove(packageName);
|
|
||||||
saveBlackList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -87,8 +56,6 @@ public class AppBlacklistActivity extends Activity {
|
|||||||
final PackageManager pm = getPackageManager();
|
final PackageManager pm = getPackageManager();
|
||||||
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||||
|
|
||||||
loadBlackList();
|
|
||||||
|
|
||||||
final List<ApplicationInfo> packageList = pm.getInstalledApplications(PackageManager.GET_META_DATA);
|
final List<ApplicationInfo> packageList = pm.getInstalledApplications(PackageManager.GET_META_DATA);
|
||||||
ListView appListView = (ListView) findViewById(R.id.appListView);
|
ListView appListView = (ListView) findViewById(R.id.appListView);
|
||||||
|
|
||||||
@ -110,7 +77,7 @@ public class AppBlacklistActivity extends Activity {
|
|||||||
deviceAppNameLabel.setText(appInfo.loadLabel(pm));
|
deviceAppNameLabel.setText(appInfo.loadLabel(pm));
|
||||||
deviceImageView.setImageDrawable(appInfo.loadIcon(pm));
|
deviceImageView.setImageDrawable(appInfo.loadIcon(pm));
|
||||||
|
|
||||||
if (blacklist.contains(appInfo.packageName)) {
|
if (GBApplication.blacklist.contains(appInfo.packageName)) {
|
||||||
checkbox.setChecked(true);
|
checkbox.setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,9 +93,9 @@ public class AppBlacklistActivity extends Activity {
|
|||||||
CheckBox checkBox = ((CheckBox) v.findViewById(R.id.item_checkbox));
|
CheckBox checkBox = ((CheckBox) v.findViewById(R.id.item_checkbox));
|
||||||
checkBox.toggle();
|
checkBox.toggle();
|
||||||
if (checkBox.isChecked()) {
|
if (checkBox.isChecked()) {
|
||||||
addToBlacklist(packageName);
|
GBApplication.addToBlacklist(packageName);
|
||||||
} else {
|
} else {
|
||||||
removeFromBlacklist(packageName);
|
GBApplication.removeFromBlacklist(packageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,7 @@ public class GBDeviceEventNotificationControl extends GBDeviceEvent {
|
|||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
DISMISS,
|
DISMISS,
|
||||||
DISMISS_ALL,
|
DISMISS_ALL,
|
||||||
OPEN
|
OPEN,
|
||||||
|
MUTE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
@ -19,8 +21,6 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
@ -36,45 +36,60 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
= "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.dismiss_all";
|
= "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.dismiss_all";
|
||||||
public static final String ACTION_OPEN
|
public static final String ACTION_OPEN
|
||||||
= "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.open";
|
= "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.open";
|
||||||
|
public static final String ACTION_MUTE
|
||||||
|
= "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.mute";
|
||||||
|
|
||||||
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
if (action.equals(ACTION_OPEN)) {
|
switch (action) {
|
||||||
StatusBarNotification[] sbns = NotificationListener.this.getActiveNotifications();
|
case ACTION_MUTE:
|
||||||
int handle = intent.getIntExtra("handle", -1);
|
case ACTION_OPEN: {
|
||||||
for (StatusBarNotification sbn : sbns) {
|
StatusBarNotification[] sbns = NotificationListener.this.getActiveNotifications();
|
||||||
if ((int) sbn.getPostTime() == handle) {
|
int handle = intent.getIntExtra("handle", -1);
|
||||||
try {
|
for (StatusBarNotification sbn : sbns) {
|
||||||
PendingIntent pi = sbn.getNotification().contentIntent;
|
if ((int) sbn.getPostTime() == handle) {
|
||||||
if (pi != null) {
|
if (action.equals(ACTION_OPEN)) {
|
||||||
pi.send();
|
try {
|
||||||
|
PendingIntent pi = sbn.getNotification().contentIntent;
|
||||||
|
if (pi != null) {
|
||||||
|
pi.send();
|
||||||
|
}
|
||||||
|
} catch (PendingIntent.CanceledException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ACTION_MUTE
|
||||||
|
LOG.info("going to mute " + sbn.getPackageName());
|
||||||
|
GBApplication.addToBlacklist(sbn.getPackageName());
|
||||||
}
|
}
|
||||||
} catch (PendingIntent.CanceledException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (action.equals(ACTION_DISMISS)) {
|
case ACTION_DISMISS: {
|
||||||
StatusBarNotification[] sbns = NotificationListener.this.getActiveNotifications();
|
StatusBarNotification[] sbns = NotificationListener.this.getActiveNotifications();
|
||||||
int handle = intent.getIntExtra("handle", -1);
|
int handle = intent.getIntExtra("handle", -1);
|
||||||
for (StatusBarNotification sbn : sbns) {
|
for (StatusBarNotification sbn : sbns) {
|
||||||
if ((int) sbn.getPostTime() == handle) {
|
if ((int) sbn.getPostTime() == handle) {
|
||||||
if (GBApplication.isRunningLollipopOrLater()) {
|
if (GBApplication.isRunningLollipopOrLater()) {
|
||||||
String key = sbn.getKey();
|
String key = sbn.getKey();
|
||||||
NotificationListener.this.cancelNotification(key);
|
NotificationListener.this.cancelNotification(key);
|
||||||
} else {
|
} else {
|
||||||
int id = sbn.getId();
|
int id = sbn.getId();
|
||||||
String pkg = sbn.getPackageName();
|
String pkg = sbn.getPackageName();
|
||||||
String tag = sbn.getTag();
|
String tag = sbn.getTag();
|
||||||
NotificationListener.this.cancelNotification(pkg, tag, id);
|
NotificationListener.this.cancelNotification(pkg, tag, id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (action.equals(ACTION_DISMISS_ALL)) {
|
case ACTION_DISMISS_ALL:
|
||||||
NotificationListener.this.cancelAllNotifications();
|
NotificationListener.this.cancelAllNotifications();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -87,6 +102,7 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
filterLocal.addAction(ACTION_OPEN);
|
filterLocal.addAction(ACTION_OPEN);
|
||||||
filterLocal.addAction(ACTION_DISMISS);
|
filterLocal.addAction(ACTION_DISMISS);
|
||||||
filterLocal.addAction(ACTION_DISMISS_ALL);
|
filterLocal.addAction(ACTION_DISMISS_ALL);
|
||||||
|
filterLocal.addAction(ACTION_MUTE);
|
||||||
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
|
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,13 +170,24 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet<String> blacklist = (HashSet<String>) sharedPrefs.getStringSet("package_blacklist", null);
|
if (GBApplication.blacklist != null && GBApplication.blacklist.contains(source)) {
|
||||||
if (blacklist != null && blacklist.contains(source)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set application icons for generic notifications
|
|
||||||
NotificationSpec notificationSpec = new NotificationSpec();
|
NotificationSpec notificationSpec = new NotificationSpec();
|
||||||
|
|
||||||
|
// determinate Source App Name ("Label")
|
||||||
|
PackageManager pm = getPackageManager();
|
||||||
|
ApplicationInfo ai = null;
|
||||||
|
try {
|
||||||
|
ai = pm.getApplicationInfo(source, 0);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (ai != null) {
|
||||||
|
notificationSpec.sourceName = (String) pm.getApplicationLabel(ai);
|
||||||
|
}
|
||||||
|
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case "org.mariotaku.twidere":
|
case "org.mariotaku.twidere":
|
||||||
case "com.twitter.android":
|
case "com.twitter.android":
|
||||||
|
@ -220,6 +220,9 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
|
|||||||
case OPEN:
|
case OPEN:
|
||||||
action = NotificationListener.ACTION_OPEN;
|
action = NotificationListener.ACTION_OPEN;
|
||||||
break;
|
break;
|
||||||
|
case MUTE:
|
||||||
|
action = NotificationListener.ACTION_MUTE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
Intent notificationListenerIntent = new Intent(action);
|
Intent notificationListenerIntent = new Intent(action);
|
||||||
|
@ -409,10 +409,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
if (isFw3x) {
|
if (isFw3x) {
|
||||||
// 3.x notification
|
// 3.x notification
|
||||||
//return encodeTimelinePin(id, (int) ((ts + 600) & 0xffffffffL), (short) 90, PebbleIconID.TIMELINE_CALENDAR, title); // really, this is just for testing
|
//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, hasHandle, notificationSpec.type);
|
return encodeBlobdbNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, notificationSpec.sourceName, hasHandle, notificationSpec.type);
|
||||||
} else if (mForceProtocol || notificationSpec.type != NotificationType.EMAIL) {
|
} else if (mForceProtocol || notificationSpec.type != NotificationType.EMAIL) {
|
||||||
// 2.x notification
|
// 2.x notification
|
||||||
return encodeExtensibleNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, hasHandle);
|
return encodeExtensibleNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, notificationSpec.sourceName, hasHandle);
|
||||||
} else {
|
} else {
|
||||||
// 1.x notification on FW 2.X
|
// 1.x notification on FW 2.X
|
||||||
String[] parts = {title, notificationSpec.body, ts.toString(), subtitle};
|
String[] parts = {title, notificationSpec.body, ts.toString(), subtitle};
|
||||||
@ -455,7 +455,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
return encodeSetCallState("Where are you?", "Gadgetbridge", start ? ServiceCommand.CALL_INCOMING : ServiceCommand.CALL_END);
|
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, boolean hasHandle) {
|
private static byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle) {
|
||||||
final short ACTION_LENGTH_MIN = 10;
|
final short ACTION_LENGTH_MIN = 10;
|
||||||
|
|
||||||
String[] parts = {title, subtitle, body};
|
String[] parts = {title, subtitle, body};
|
||||||
@ -465,12 +465,18 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
short actions_length;
|
short actions_length;
|
||||||
String dismiss_string;
|
String dismiss_string;
|
||||||
String open_string = "Open on phone";
|
String open_string = "Open on phone";
|
||||||
|
String mute_string = "Mute";
|
||||||
|
if (sourceName != null) {
|
||||||
|
mute_string += " " + sourceName;
|
||||||
|
}
|
||||||
|
|
||||||
byte dismiss_action_id;
|
byte dismiss_action_id;
|
||||||
|
|
||||||
if (hasHandle) {
|
if (hasHandle) {
|
||||||
actions_count = 2;
|
actions_count = 3;
|
||||||
dismiss_string = "Dismiss";
|
dismiss_string = "Dismiss";
|
||||||
dismiss_action_id = 0x02;
|
dismiss_action_id = 0x02;
|
||||||
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.getBytes().length + open_string.getBytes().length);
|
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.getBytes().length + open_string.getBytes().length + mute_string.getBytes().length);
|
||||||
} else {
|
} else {
|
||||||
actions_count = 1;
|
actions_count = 1;
|
||||||
dismiss_string = "Dismiss all";
|
dismiss_string = "Dismiss all";
|
||||||
@ -539,11 +545,19 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
// open action
|
// open action
|
||||||
if (hasHandle) {
|
if (hasHandle) {
|
||||||
buf.put((byte) 0x01);
|
buf.put((byte) 0x01);
|
||||||
buf.put((byte) 0x02); // dissmiss - FIXME: find out how to answer to 2.x generic actions
|
buf.put((byte) 0x02); // generic
|
||||||
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)
|
||||||
buf.putShort((short) open_string.getBytes().length);
|
buf.putShort((short) open_string.getBytes().length);
|
||||||
buf.put(open_string.getBytes());
|
buf.put(open_string.getBytes());
|
||||||
|
|
||||||
|
buf.put((byte) 0x04);
|
||||||
|
buf.put((byte) 0x02); // generic
|
||||||
|
buf.put((byte) 0x01); // number attributes
|
||||||
|
buf.put((byte) 0x01); // attribute id (title)
|
||||||
|
buf.putShort((short) mute_string.getBytes().length);
|
||||||
|
buf.put(mute_string.getBytes());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf.array();
|
return buf.array();
|
||||||
@ -619,7 +633,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
return encodeBlobdb(uuid, BLOBDB_INSERT, BLOBDB_PIN, buf.array());
|
return encodeBlobdb(uuid, BLOBDB_INSERT, BLOBDB_PIN, buf.array());
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, boolean hasHandle, NotificationType notificationType) {
|
private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, String sourceName, boolean hasHandle, NotificationType notificationType) {
|
||||||
final short NOTIFICATION_PIN_LENGTH = 46;
|
final short NOTIFICATION_PIN_LENGTH = 46;
|
||||||
final short ACTION_LENGTH_MIN = 10;
|
final short ACTION_LENGTH_MIN = 10;
|
||||||
|
|
||||||
@ -670,12 +684,17 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
short actions_length;
|
short actions_length;
|
||||||
String dismiss_string;
|
String dismiss_string;
|
||||||
String open_string = "Open on phone";
|
String open_string = "Open on phone";
|
||||||
|
String mute_string = "Mute";
|
||||||
|
if (sourceName != null) {
|
||||||
|
mute_string += " " + sourceName;
|
||||||
|
}
|
||||||
|
|
||||||
byte dismiss_action_id;
|
byte dismiss_action_id;
|
||||||
if (hasHandle) {
|
if (hasHandle) {
|
||||||
actions_count = 2;
|
actions_count = 3;
|
||||||
dismiss_string = "Dismiss";
|
dismiss_string = "Dismiss";
|
||||||
dismiss_action_id = 0x02;
|
dismiss_action_id = 0x02;
|
||||||
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.getBytes().length + open_string.getBytes().length);
|
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.getBytes().length + open_string.getBytes().length + mute_string.getBytes().length);
|
||||||
} else {
|
} else {
|
||||||
actions_count = 1;
|
actions_count = 1;
|
||||||
dismiss_string = "Dismiss all";
|
dismiss_string = "Dismiss all";
|
||||||
@ -751,7 +770,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
buf.putShort((short) dismiss_string.getBytes().length);
|
buf.putShort((short) dismiss_string.getBytes().length);
|
||||||
buf.put(dismiss_string.getBytes());
|
buf.put(dismiss_string.getBytes());
|
||||||
|
|
||||||
// open action
|
// open and mute actions
|
||||||
if (hasHandle) {
|
if (hasHandle) {
|
||||||
buf.put((byte) 0x01);
|
buf.put((byte) 0x01);
|
||||||
buf.put((byte) 0x02); // generic action
|
buf.put((byte) 0x02); // generic action
|
||||||
@ -759,11 +778,18 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
buf.put((byte) 0x01); // attribute id (title)
|
buf.put((byte) 0x01); // attribute id (title)
|
||||||
buf.putShort((short) open_string.getBytes().length);
|
buf.putShort((short) open_string.getBytes().length);
|
||||||
buf.put(open_string.getBytes());
|
buf.put(open_string.getBytes());
|
||||||
|
|
||||||
|
buf.put((byte) 0x04);
|
||||||
|
buf.put((byte) 0x02); // generic action
|
||||||
|
buf.put((byte) 0x01); // number attributes
|
||||||
|
buf.put((byte) 0x01); // attribute id (title)
|
||||||
|
buf.putShort((short) mute_string.getBytes().length);
|
||||||
|
buf.put(mute_string.getBytes());
|
||||||
}
|
}
|
||||||
return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array());
|
return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array());
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encodeActionResponse2x(int id, int iconId, String caption) {
|
public byte[] encodeActionResponse2x(int id, byte actionId, int iconId, String caption) {
|
||||||
short length = (short) (18 + caption.getBytes().length);
|
short length = (short) (18 + caption.getBytes().length);
|
||||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length);
|
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length);
|
||||||
buf.order(ByteOrder.BIG_ENDIAN);
|
buf.order(ByteOrder.BIG_ENDIAN);
|
||||||
@ -772,7 +798,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
buf.put(NOTIFICATIONACTION_RESPONSE);
|
buf.put(NOTIFICATIONACTION_RESPONSE);
|
||||||
buf.putInt(id);
|
buf.putInt(id);
|
||||||
buf.put((byte) 0x01); // action id?
|
buf.put(actionId);
|
||||||
buf.put(NOTIFICATIONACTION_ACK);
|
buf.put(NOTIFICATIONACTION_ACK);
|
||||||
buf.put((byte) 2); //nr of attributes
|
buf.put((byte) 2); //nr of attributes
|
||||||
buf.put((byte) 6); // icon
|
buf.put((byte) 6); // icon
|
||||||
@ -1386,7 +1412,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
if (command == 0x02) {
|
if (command == 0x02) {
|
||||||
int id = buf.getInt();
|
int id = buf.getInt();
|
||||||
byte action = buf.get();
|
byte action = buf.get();
|
||||||
if (action >= 0x01 && action <= 0x03) {
|
if (action >= 0x01 && action <= 0x04) {
|
||||||
GBDeviceEventNotificationControl devEvtNotificationControl = new GBDeviceEventNotificationControl();
|
GBDeviceEventNotificationControl devEvtNotificationControl = new GBDeviceEventNotificationControl();
|
||||||
devEvtNotificationControl.handle = id;
|
devEvtNotificationControl.handle = id;
|
||||||
GBDeviceEventSendBytes sendBytesAck = null;
|
GBDeviceEventSendBytes sendBytesAck = null;
|
||||||
@ -1395,7 +1421,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
case 0x01:
|
case 0x01:
|
||||||
devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.OPEN;
|
devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.OPEN;
|
||||||
sendBytesAck = new GBDeviceEventSendBytes();
|
sendBytesAck = new GBDeviceEventSendBytes();
|
||||||
sendBytesAck.encodedBytes = encodeActionResponse2x(id, 6, "Opened");
|
sendBytesAck.encodedBytes = encodeActionResponse2x(id, action, 6, "Opened");
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.DISMISS;
|
devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.DISMISS;
|
||||||
@ -1403,6 +1429,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
case 0x03:
|
case 0x03:
|
||||||
devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.DISMISS_ALL;
|
devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.DISMISS_ALL;
|
||||||
break;
|
break;
|
||||||
|
case 0x04:
|
||||||
|
devEvtNotificationControl.event = GBDeviceEventNotificationControl.Event.MUTE;
|
||||||
|
sendBytesAck = new GBDeviceEventSendBytes();
|
||||||
|
sendBytesAck.encodedBytes = encodeActionResponse2x(id, action, 6, "Muted");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1424,7 +1455,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
long uuid_low = buf.getLong();
|
long uuid_low = buf.getLong();
|
||||||
int id = (int) (uuid_low & 0xffffffff);
|
int id = (int) (uuid_low & 0xffffffff);
|
||||||
byte action = buf.get();
|
byte action = buf.get();
|
||||||
if (action >= 0x01 && action <= 0x03) {
|
if (action >= 0x01 && action <= 0x04) {
|
||||||
GBDeviceEventNotificationControl dismissNotification = new GBDeviceEventNotificationControl();
|
GBDeviceEventNotificationControl dismissNotification = new GBDeviceEventNotificationControl();
|
||||||
dismissNotification.handle = id;
|
dismissNotification.handle = id;
|
||||||
String caption = "undefined";
|
String caption = "undefined";
|
||||||
@ -1445,6 +1476,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
caption = "All dismissed";
|
caption = "All dismissed";
|
||||||
icon_id = PebbleIconID.RESULT_DISMISSED;
|
icon_id = PebbleIconID.RESULT_DISMISSED;
|
||||||
break;
|
break;
|
||||||
|
case 0x04:
|
||||||
|
dismissNotification.event = GBDeviceEventNotificationControl.Event.MUTE;
|
||||||
|
caption = "Muted";
|
||||||
|
icon_id = PebbleIconID.RESULT_MUTE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
GBDeviceEventSendBytes sendBytesAck = new GBDeviceEventSendBytes();
|
GBDeviceEventSendBytes sendBytesAck = new GBDeviceEventSendBytes();
|
||||||
sendBytesAck.encodedBytes = encodeActionResponse(new UUID(uuid_high, uuid_low), icon_id, caption);
|
sendBytesAck.encodedBytes = encodeActionResponse(new UUID(uuid_high, uuid_low), icon_id, caption);
|
||||||
|
@ -308,7 +308,7 @@ public class GB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void updateTransferNotification(String text, boolean ongoing, int percentage, Context context) {
|
public static void updateTransferNotification(String text, boolean ongoing, int percentage, Context context) {
|
||||||
if(percentage == 100) {
|
if (percentage == 100) {
|
||||||
removeNotification(NOTIFICATION_ID_TRANSFER, context);
|
removeNotification(NOTIFICATION_ID_TRANSFER, context);
|
||||||
} else {
|
} else {
|
||||||
Notification notification = createTransferNotification(text, ongoing, percentage, context);
|
Notification notification = createTransferNotification(text, ongoing, percentage, context);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user