Cache notifications while devices are out of range (opt-in)

This commit is contained in:
Arjan Schrijver 2023-03-31 21:07:56 +02:00
parent 340db0ca15
commit b892748b15
5 changed files with 58 additions and 1 deletions

View File

@ -17,6 +17,7 @@
* Zepp OS: Fix setting of unknown configuration values
* Add Croatian transliterator
* Fix restoring app notification/pebble blacklist preferences on import
* Cache notifications while devices are out of range (opt-in)
#### 0.73.0
* Initial support for Amazfit T-Rex 2

View File

@ -772,7 +772,7 @@ public class NotificationListener extends NotificationListenerService {
notificationsActive.removeAll(notificationsToRemove);
// Send notification remove request to device
List<GBDevice> devices = GBApplication.app().getDeviceManager().getSelectedDevices();
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
for(GBDevice device : devices){
Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()));
if (devicePrefs.getBoolean("autoremove_notifications", true)) {

View File

@ -45,6 +45,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
@ -310,6 +311,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
private DeviceSupportFactory mFactory;
private final ArrayList<DeviceStruct> deviceStructs = new ArrayList<>(1);
private final HashMap<String, ArrayList<Intent>> cachedNotifications = new HashMap<>();
private PhoneCallReceiver mPhoneCallReceiver = null;
private SMSReceiver mSMSReceiver = null;
@ -347,6 +349,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
private final String COMMAND_BLUETOOTH_CONNECT = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_CONNECT";
private final String ACTION_DEVICE_CONNECTED = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_CONNECTED";
private final int NOTIFICATIONS_CACHE_MAX = 10; // maximum amount of notifications to cache per device while disconnected
private boolean allowBluetoothIntentApi = false;
private void sendDeviceConnectedBroadcast(String address){
@ -442,6 +445,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
if(subject == GBDevice.DeviceUpdateSubject.DEVICE_STATE && device.isInitialized()){
LOG.debug("device state update reason");
sendDeviceConnectedBroadcast(device.getAddress());
sendCachedNotifications(device);
}
}
}
@ -626,6 +630,28 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
for(GBDevice device : getGBDevices()){
if(isDeviceInitialized(device)){
targetedDevices.add(device);
} else if (isDeviceReconnecting(device) && action.equals(ACTION_NOTIFICATION) && GBApplication.getPrefs().getBoolean("notification_cache_while_disconnected", false)) {
if (!cachedNotifications.containsKey(device.getAddress())) {
cachedNotifications.put(device.getAddress(), new ArrayList<>());
}
ArrayList<Intent> notifCache = cachedNotifications.get(device.getAddress());
notifCache.add(intent);
if (notifCache.size() > NOTIFICATIONS_CACHE_MAX) {
// remove the oldest notification if the maximum is reached
notifCache.remove(0);
}
} else if (action.equals(ACTION_DELETE_NOTIFICATION)) {
ArrayList<Intent> notifCache = cachedNotifications.get(device.getAddress());
if (notifCache != null) {
int notifId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
ArrayList<Intent> toRemove = new ArrayList<>();
for (Intent cached : notifCache) {
if (notifId == cached.getIntExtra(EXTRA_NOTIFICATION_ID, -1)) {
toRemove.add(cached);
}
}
notifCache.removeAll(toRemove);
}
}
}
}
@ -1088,6 +1114,15 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
return false;
}
private boolean isDeviceReconnecting(GBDevice device) {
for(DeviceStruct struct : deviceStructs){
if(struct.getDevice().getAddress().compareToIgnoreCase(device.getAddress()) == 0){
return struct.getDevice().getStateOrdinal() == GBDevice.State.WAITING_FOR_RECONNECT.ordinal();
}
}
return false;
}
private boolean deviceHasCalendarReceiverRegistered(GBDevice device){
for (CalendarReceiver receiver: mCalendarReceiver){
if(receiver.getGBDevice().equals(device)){
@ -1275,6 +1310,18 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
}
}
private void sendCachedNotifications(GBDevice device) {
ArrayList<Intent> notifCache = cachedNotifications.get(device.getAddress());
if (notifCache == null) return;
try {
while (notifCache.size() > 0) {
handleAction(notifCache.remove(0), ACTION_NOTIFICATION, device);
}
} catch (DeviceNotFoundException e) {
LOG.error("Error while sending cached notifications to "+device.getAliasOrName(), e);
}
}
@Override
public void onDestroy() {
if (hasPrefs()) {

View File

@ -247,6 +247,8 @@
<string name="pref_summary_notifications_ignore_low_priority">Do not send low and minimum priority notifications to the watch</string>
<string name="pref_title_notification_prefer_long_text">Prefer long notification text</string>
<string name="pref_summary_notification_prefer_long_text">If available, send the long notification text to the device</string>
<string name="pref_title_notification_cache_while_disconnected">Cache while out of range</string>
<string name="pref_summary_notification_cache_while_disconnected">Send missed notifications when a device reconnects after being out of range</string>
<string name="pref_title_notification_filter">Do Not Disturb</string>
<string name="pref_summary_notification_filter">Block all notifications when Do Not Disturb is enabled on the phone</string>
<string name="pref_title_notification_media_ignores_application_list">Media notifications ignore app list</string>

View File

@ -31,6 +31,13 @@
android:title="@string/pref_title_notification_prefer_long_text"
android:summary="@string/pref_summary_notification_prefer_long_text" />
<CheckBoxPreference
android:defaultValue="false"
android:key="notification_cache_while_disconnected"
android:layout="@layout/preference_checkbox"
android:title="@string/pref_title_notification_cache_while_disconnected"
android:summary="@string/pref_summary_notification_cache_while_disconnected" />
<CheckBoxPreference
android:defaultValue="false"
android:key="minimize_priority"