1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-29 13:26:50 +01:00

Add Navigation handling to Bangle.js

Add extra 'ETA' field to NavigationInfoSpec
Allow Local Notifications from Google Maps to be parsed into NavigationInfoSpec by GoogleMapsNotificationHandler

Moved notification handling after blacklist check as per https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/3136#issuecomment-920095

Ensure we don't create a nav message for 'Location Shared with you' messages.
Recognise 'ft' as a distance unit and convert accordingly

Google Maps navigation: Adding new recognised icons, and removing warnings/errors from file
This commit is contained in:
Gordon Williams 2023-06-09 08:47:10 +01:00
parent e01d3ecfa7
commit 735f27d5bf
8 changed files with 804 additions and 3 deletions

View File

@ -205,4 +205,9 @@ public class BangleJSCoordinator extends AbstractBLEDeviceCoordinator {
for (int i=0; i<settings.size(); i++) settingsInt[i] = settings.get(i); for (int i=0; i<settings.size(); i++) settingsInt[i] = settings.get(i);
return settingsInt; return settingsInt;
} }
@Override
public boolean supportsNavigation() {
return true;
}
} }

View File

@ -71,6 +71,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilter;
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterDao; import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterDao;
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntry; import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntry;
import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntryDao; import nodomain.freeyourgadget.gadgetbridge.entities.NotificationFilterEntryDao;
import nodomain.freeyourgadget.gadgetbridge.externalevents.notifications.GoogleMapsNotificationHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.AppNotificationType; import nodomain.freeyourgadget.gadgetbridge.model.AppNotificationType;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
@ -128,6 +129,8 @@ public class NotificationListener extends NotificationListenerService {
private Runnable mSetMusicInfoRunnable = null; private Runnable mSetMusicInfoRunnable = null;
private Runnable mSetMusicStateRunnable = null; private Runnable mSetMusicStateRunnable = null;
private GoogleMapsNotificationHandler googleMapsNotificationHandler = new GoogleMapsNotificationHandler();
private final BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override @Override
@ -277,6 +280,9 @@ public class NotificationListener extends NotificationListenerService {
if (shouldIgnoreSource(sbn)) return; if (shouldIgnoreSource(sbn)) return;
/* Check for navigation notifications and ignore if we're handling them */
if (googleMapsNotificationHandler.handle(getApplicationContext(), sbn)) return;
// If media notifications do NOT ignore app list, check them after // If media notifications do NOT ignore app list, check them after
if (!mediaIgnoresAppList && handleMediaSessionNotification(sbn)) return; if (!mediaIgnoresAppList && handleMediaSessionNotification(sbn)) return;
@ -730,6 +736,8 @@ public class NotificationListener extends NotificationListenerService {
notificationStack.remove(sbn.getPackageName()); notificationStack.remove(sbn.getPackageName());
googleMapsNotificationHandler.handleRemove(sbn);
if (isServiceNotRunningAndShouldIgnoreNotifications()) return; if (isServiceNotRunningAndShouldIgnoreNotifications()) return;
final Prefs prefs = GBApplication.getPrefs(); final Prefs prefs = GBApplication.getPrefs();

View File

@ -0,0 +1,757 @@
package nodomain.freeyourgadget.gadgetbridge.externalevents.notifications;
import android.app.Notification;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.service.notification.StatusBarNotification;
import androidx.core.app.NotificationCompat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.model.NavigationInfoSpec;
public class GoogleMapsNotificationHandler {
private static final Logger LOG = LoggerFactory.getLogger(GoogleMapsNotificationHandler.class);
static class IconType {
int[] icon;
int iconType;
public IconType(int iconType, int[] icon) {
this.icon = icon;
this.iconType = iconType;
}
}
List<IconType> knownImages;
public GoogleMapsNotificationHandler() {
knownImages = new ArrayList<>();
knownImages.add(new IconType(NavigationInfoSpec.ACTION_CONTINUE, new int[]{
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000001000000000000000,
0b00000000000000011100000000000000,
0b00000000000000111110000000000000,
0b00000000000011111111000000000000,
0b00000000000111111111100000000000,
0b00000000001111111111110000000000,
0b00000000011111111111111000000000,
0b00000000111110111101111100000000,
0b00000000111100111100111100000000,
0b00000000011000111100011100000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000000000000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000000000000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_CONTINUE, new int[]{
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000001000000000000000,
0b00000000000000011100000000000000,
0b00000000000000111110000000000000,
0b00000000000011111111000000000000,
0b00000000000111111111100000000000,
0b00000000001111111111110000000000,
0b00000000011111111111111000000000,
0b00000000111110111101111100000000,
0b00000000111100111100111100000000,
0b00000000011000111100011100000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_TURN_LEFT, new int[]{
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000001100000000000000000000,
0b00000000011110000000000000000000,
0b00000000111110000000000000000000,
0b00000001111100000000000000000000,
0b00000011111000000000000000000000,
0b00000111110000000000000000000000,
0b00001111111111111111111110000000,
0b00011111111111111111111111100000,
0b00001111111111111111111111110000,
0b00000111100000000000000111111000,
0b00000011110000000000000001111000,
0b00000011111000000000000000111000,
0b00000001111100000000000000111000,
0b00000000111110000000000000111000,
0b00000000011110000000000000111000,
0b00000000000100000000000000111000,
0b00000000000000000000000000111000,
0b00000000000000000000000000111000,
0b00000000000000000000000000111000,
0b00000000000000000000000000111000,
0b00000000000000000000000000111000,
0b00000000000000000000000000111000,
0b00000000000000000000000000111000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_TURN_RIGHT, new int[]{
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000110000000000,
0b00000000000000000001111000000000,
0b00000000000000000001111100000000,
0b00000000000000000000111110000000,
0b00000000000000000000011111000000,
0b00000000000000000000001111100000,
0b00000001111111111111111111110000,
0b00000111111111111111111111111000,
0b00001111111111111111111111111000,
0b00001111100000000000000111110000,
0b00011110000000000000001111100000,
0b00011100000000000000011111000000,
0b00011100000000000000111110000000,
0b00011100000000000001111100000000,
0b00011100000000000001111000000000,
0b00011100000000000000100000000000,
0b00011100000000000000000000000000,
0b00011100000000000000000000000000,
0b00011100000000000000000000000000,
0b00011100000000000000000000000000,
0b00011100000000000000000000000000,
0b00011100000000000000000000000000,
0b00011100000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_TURN_LEFT_SLIGHTLY, new int[]{
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000111111111111000000000000,
0b00000000111111111111000000000000,
0b00000000111111111111000000000000,
0b00000000111111000000000000000000,
0b00000000111111100000000000000000,
0b00000000111111110000000000000000,
0b00000000111011111000000000000000,
0b00000000111001111100000000000000,
0b00000000111000111110000000000000,
0b00000000111000011111000000000000,
0b00000000111000001111100000000000,
0b00000000111000000111110000000000,
0b00000000000000000011111000000000,
0b00000000000000000001111000000000,
0b00000000000000000000111100000000,
0b00000000000000000000011100000000,
0b00000000000000000000011110000000,
0b00000000000000000000011110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_TURN_RIGHT_SLIGHTLY, new int[]{
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000011111111111100000000,
0b00000000000011111111111100000000,
0b00000000000011111111111100000000,
0b00000000000000000011111100000000,
0b00000000000000000111111100000000,
0b00000000000000001111111100000000,
0b00000000000000011111011100000000,
0b00000000000000111110011100000000,
0b00000000000001111100011100000000,
0b00000000000011111000011100000000,
0b00000000000111110000011100000000,
0b00000000001111100000011100000000,
0b00000000011111000000000000000000,
0b00000000011110000000000000000000,
0b00000000111100000000000000000000,
0b00000000111000000000000000000000,
0b00000001111000000000000000000000,
0b00000001111000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_FINISH, new int[]{
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000011111111000000000000,
0b00000000001111111111110000000000,
0b00000000011111000011111000000000,
0b00000000111100000000111100000000,
0b00000001111000000000011110000000,
0b00000001110000000000001110000000,
0b00000011100000000000000111000000,
0b00000011100000000000000111000000,
0b00000011000000111100000011000000,
0b00000111000001111110000011100000,
0b00000111000001111110000011100000,
0b00000111000000111100000011100000,
0b00000111000000111100000011100000,
0b00000011000000000000000011000000,
0b00000011100000000000000111000000,
0b00000011100000000000000111000000,
0b00000001110000000000001110000000,
0b00000000111000000000011100000000,
0b00000000111100000000111100000000,
0b00000000011100000000111000000000,
0b00000000001110000001110000000000,
0b00000000000111000011100000000000,
0b00000000000011111111000000000000,
0b00000000000001111110000000000000,
0b00000000000000111100000000000000,
0b00000000000000011000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_FINISH, new int[]{
0b00000000000000000000000000000000,
0b00000000111000000000000000000000,
0b00000111111110000000000000000000,
0b00001111111111100000000000000000,
0b00011110000011110000000000000000,
0b00111100000001110000000000000000,
0b00111000000000111000000000000000,
0b00110000010000111000000000000000,
0b01110000111000011000000000000000,
0b01110001111000011000000000000000,
0b01110000111000011000000000000000,
0b00110000000000111000000000000000,
0b00111000000000111000000000000000,
0b00111000000001110000000000000000,
0b00011100000001110000000000000000,
0b00011100000011100011000111100000,
0b00001110000011100111000111100000,
0b00001111000111000111111111110000,
0b00000111001111001111111111110000,
0b00000011101110011111111111110000,
0b00000011111100011111000111110000,
0b00000001111000111111000111111000,
0b00000000111000111111000111111000,
0b00000000010001111111111111111000,
0b00000000000001111111111111111100,
0b00000000000001111111000111111100,
0b00000000000011111111000111111100,
0b00000000000011111111000111111110,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_LEFT, new int[]{
0b000000000000000000000000000000000,
0b000000000000000000000000000000000,
0b000000000000000000000000000000000,
0b000000000000000000000000000000000,
0b000000001111111111100000000000000,
0b000000001111111111110000000000000,
0b000000001111111111110000000000000,
0b000000001111100000000000000000000,
0b000000001111110000000000000000000,
0b000000001111111000000000000000000,
0b000000001111111100000000000000000,
0b000000001110111110000000000000000,
0b000000001110011111000000000000000,
0b000000001110001111100000000000000,
0b000000001110001111000000000000000,
0b000000001110011110000000000000000,
0b000000000000011110000000000000000,
0b000000000000011100000000000000000,
0b000000000000011100000000000000000,
0b000000000000011110000000000000000,
0b000000000000011110000000000000000,
0b000000000000001111000000000000000,
0b000000000000000111111100000000000,
0b000000000000000111111100000000000,
0b000000000000000001111100000000000,
0b000000000000000000011100000000000,
0b000000000000000000011100000000000,
0b000000000000000000011100000000000,
0b000000000000000000000000000000000,
0b000000000000000000000000000000000,
0b000000000000000000000000000000000,
0b000000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_RIGHT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000111111111110000000,
0b00000000000001111111111110000000,
0b00000000000001111111111110000000,
0b00000000000000000000111110000000,
0b00000000000000000001111110000000,
0b00000000000000000011111110000000,
0b00000000000000000111111110000000,
0b00000000000000001111101110000000,
0b00000000000000011111001110000000,
0b00000000000000111110001110000000,
0b00000000000000011110001110000000,
0b00000000000000001111001110000000,
0b00000000000000001111000000000000,
0b00000000000000000111000000000000,
0b00000000000000000111000000000000,
0b00000000000000001111000000000000,
0b00000000000000001111000000000000,
0b00000000000000011110000000000000,
0b00000000000111111100000000000000,
0b00000000000111111100000000000000,
0b00000000000111110000000000000000,
0b00000000000111000000000000000000,
0b00000000000111000000000000000000,
0b00000000000111000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_STRAIGHT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000011000000000000000,
0b00000000000000111100000000000000,
0b00000000000001111110000000000000,
0b00000000000011111111000000000000,
0b00000000000111111111100000000000,
0b00000000001111111111110000000000,
0b00000000011110111101111000000000,
0b00000000111100111100111100000000,
0b00000000111000111100011100000000,
0b00000000000000111100000000000000,
0b00000000000011111100000000000000,
0b00000000000111111100000000000000,
0b00000000001111111100000000000000,
0b00000000011111000000000000000000,
0b00000000011110000000000000000000,
0b00000000011100000000000000000000,
0b00000000011100000000000000000000,
0b00000000011100000000000000000000,
0b00000000011100000000000000000000,
0b00000000011110000000000000000000,
0b00000000011111000000000000000000,
0b00000000001111111100000000000000,
0b00000000000111111100000000000000,
0b00000000000011111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_STRAIGHT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000011000000000000000,
0b00000000000000111100000000000000,
0b00000000000001111110000000000000,
0b00000000000011111111000000000000,
0b00000000000111111111100000000000,
0b00000000001111111111110000000000,
0b00000000011110111101111000000000,
0b00000000111100111100111100000000,
0b00000000111000111100011100000000,
0b00000000000000111100000000000000,
0b00000000000000111111000000000000,
0b00000000000000111111100000000000,
0b00000000000000111111110000000000,
0b00000000000000000011111000000000,
0b00000000000000000001111000000000,
0b00000000000000000000111000000000,
0b00000000000000000000111000000000,
0b00000000000000000000111000000000,
0b00000000000000000000111000000000,
0b00000000000000000001111000000000,
0b00000000000000000011111000000000,
0b00000000000000111111110000000000,
0b00000000000000111111100000000000,
0b00000000000000111111000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000111100000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_LEFT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000011000000000000000000000,
0b00000000111100000000000000000000,
0b00000001111100000000000000000000,
0b00000011111000000000000000000000,
0b00000111110000000000000000000000,
0b00001111100000000000000000000000,
0b00011111111111111110000000000000,
0b00111111111111111110000000000000,
0b00111111111111111111000000000000,
0b00011111111111111111000000000000,
0b00001111100000001111000000000000,
0b00000111110000000111110000000000,
0b00000011111000000011111110000000,
0b00000001111100000011111111000000,
0b00000000111100000000111110000000,
0b00000000011000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_RIGHT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000011000000000,
0b00000000000000000000111100000000,
0b00000000000000000000111110000000,
0b00000000000000000000011111000000,
0b00000000000000000000001111100000,
0b00000000000000000000000111110000,
0b00000000000001111111111111111000,
0b00000000000001111111111111111100,
0b00000000000011111111111111111100,
0b00000000000011111111111111111000,
0b00000000000011110000000111110000,
0b00000000001111100000001111100000,
0b00000001111111000000011111000000,
0b00000011111111000000111110000000,
0b00000001111100000000111100000000,
0b00000001110000000000011000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_LEFT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000111111111111000000000000000,
0b00000111111111111000000000000000,
0b00000111111111111000000000000000,
0b00000111111100000000000000000000,
0b00000111111100000000000000000000,
0b00000111111110000000000000000000,
0b00000111111111000000000000000000,
0b00000111101111101111111000000000,
0b00000111100111111111111100000000,
0b00000111100011111111111110000000,
0b00000111100001111100011111000000,
0b00000011000000110000001111000000,
0b00000000000000000000000111100000,
0b00000000000000000000000111100000,
0b00000000000000000000000111100000,
0b00000000000000000000000111100000,
0b00000000000000000000001111000000,
0b00000000000000000000011111000000,
0b00000000000000000111111110000000,
0b00000000000000000111111100000000,
0b00000000000000000111111000000000,
0b00000000000000000011100000000000,
0b00000000000000000011100000000000,
0b00000000000000000011100000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_RIGHT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000011111111111100000,
0b00000000000000011111111111100000,
0b00000000000000011111111111100000,
0b00000000000000000000111111100000,
0b00000000000000000000111111100000,
0b00000000000000000001111111100000,
0b00000000000000000011111111100000,
0b00000000011111110111110111100000,
0b00000000111111111111100111100000,
0b00000001111111111111000111100000,
0b00000011111000111110000111100000,
0b00000011110000001100000011000000,
0b00000111100000000000000000000000,
0b00000111100000000000000000000000,
0b00000111100000000000000000000000,
0b00000111100000000000000000000000,
0b00000011110000000000000000000000,
0b00000011111000000000000000000000,
0b00000001111111100000000000000000,
0b00000000111111100000000000000000,
0b00000000011111100000000000000000,
0b00000000000111000000000000000000,
0b00000000000111000000000000000000,
0b00000000000111000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_LEFT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000011000000000000000000000,
0b00000000111100000000111111100000,
0b00000001111100000011111111110000,
0b00000011111000000111111111111000,
0b00000111110000000111110001111100,
0b00001111100000001111000000111100,
0b00011111111111111111000000011110,
0b00111111111111111110000000011110,
0b00111111111111111110000000011110,
0b00011111111111111110000000011110,
0b00001111100000000000000000111100,
0b00000111110000000000000001111100,
0b00000011111000000000011111111000,
0b00000001111100000000011111110000,
0b00000000111100000000011111100000,
0b00000000011000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000001110000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
knownImages.add(new IconType(NavigationInfoSpec.ACTION_ROUNDABOUT_RIGHT, new int[]{
0b00000000000000000000000000000000,// GUESSED - this may not be an exact match
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000011000000000,
0b00000111111100000000111100000000,
0b00001111111111000000111110000000,
0b00011111111111100000011111000000,
0b00111110001111100000001111100000,
0b00111100000011110000000111110000,
0b01111000000011111111111111111000,
0b01111000000001111111111111111100,
0b01111000000001111111111111111100,
0b01111000000001111111111111111000,
0b00111100000000000000000111110000,
0b00111110000000000000001111100000,
0b00011111111000000000011111000000,
0b00001111111000000000111110000000,
0b00000111111000000000111100000000,
0b00000001110000000000011000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000001110000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000
}));
}
public boolean handle(Context context, StatusBarNotification sbn) {
if (sbn.getPackageName().equals("com.google.android.apps.maps")) {
Notification notification = sbn.getNotification();
if (!NotificationCompat.getLocalOnly(notification))
return false; // ignore non-local notifications
String distance = (notification.extras.get("android.title")==null) ? "" :
notification.extras.get("android.title").toString(); // eg 100 yd
String instruction = (notification.extras.get("android.text")==null) ? "" :
notification.extras.get("android.text").toString(); // eg: High St towards Blah
String navLine = (notification.extras.get("android.subText")==null) ? "" :
notification.extras.get("android.subText").toString().replaceAll("\u00A0", " "); // eg: 13 min · 4.6 mi · 11:55 ETA
String[] navLines = navLine.split("·");
for (int i = 0; i < navLines.length; i++) navLines[i] = navLines[i].trim();
if (navLines.length < 3) return false; // not in the format we expected - might be 'Shared with you' notification
// navLines now has at least 3 elements
LOG.info("Navigation: " + instruction + "," + distance + "," + navLines[0] + "," + navLines[1] + "," + navLines[2]);
int matchedIcon = -1;
// getLargeIcon only works in API 23+ - don't try and get icons on older devices
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Icon icon = notification.getLargeIcon();
if (icon != null) {
// We convert the icon to a bitmap, then to x 32x32 1bpp which we'll check against known images
Drawable drawable = icon.loadDrawable(context);
Bitmap bitmap = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
int[] pixelsRGBA = new int[32 * 32];
bitmap.getPixels(pixelsRGBA, 0, 32, 0, 0, 32, 32);
int[] pixelPack = new int[32]; // pixels packed down 1bpp
char[] pixelStringChars = new char[33 * 32];
for (int y = 0; y < 32; y++) {
int pack = 0;
for (int x = 0; x < 32; x++) {
int pixel = ((pixelsRGBA[(y * 32) + x] & 0x80000000) != 0) ? 1 : 0;
pack = (pack << 1) | pixel; // check top bit (=alpha)
pixelStringChars[x + y * 33] = (pixel != 0) ? '1' : '0';
}
pixelStringChars[32 + y * 33] = '\n';
pixelPack[y] = pack;
}
// This is now a printable string showing the image, which we can log if we don't recognise it
String pixelString = new String(pixelStringChars);
int bestDiff = 100;
for (int i = 0; i < knownImages.size(); i++) {
IconType knownImage = knownImages.get(i);
int diff = 0;
// Work out how many bits differ over the whole image
for (int j = 0; j < 32; j++)
diff += Integer.bitCount(knownImage.icon[j] ^ pixelPack[j]);
// if it's close enough, match
if (diff < 32 && diff < bestDiff) {
matchedIcon = knownImage.iconType;
bestDiff = diff;
}
}
if (matchedIcon < 0) {
LOG.info("Icon NEW:\n" + pixelString);
knownImages.add(new IconType(255, pixelPack));
}
}
}
NavigationInfoSpec navInfo = new NavigationInfoSpec();
if (matchedIcon>=0)
navInfo.nextAction = matchedIcon;
navInfo.instruction = instruction;
if (distance != null) {
float distanceMultiplier = 1;
String distanceUnit = distance.replaceAll("[\\d.\\s]", "").toLowerCase();
if (distanceUnit.equals("m")) distanceMultiplier = 1;
else if (distanceUnit.equals("mi")) distanceMultiplier = 1609.34f;
else if (distanceUnit.equals("yd")) distanceMultiplier = 0.9144f;
else if (distanceUnit.equals("ft")) distanceMultiplier = 0.3048f;
else if (distanceUnit.equals("km")) distanceMultiplier = 1000;
else LOG.info("Unknown distance unit '"+distanceUnit+"'");
try {
navInfo.distanceToTurn = Math.round(distanceMultiplier * Float.parseFloat(distance.replaceAll("[^\\d.]", "")));
} catch (NumberFormatException e) {
LOG.info("Couldn't parse distance");
}
}
if (navLines[2].contains("ETA"))
navInfo.ETA = navLines[2].replace("ETA","").trim();
GBApplication.deviceService().onSetNavigationInfo(navInfo);
return true;
}
return false;
}
public boolean handleRemove(StatusBarNotification sbn) {
if (sbn.getPackageName().equals("com.google.android.apps.maps")) {
Notification notification = sbn.getNotification();
if (!NotificationCompat.getLocalOnly(notification))
return false; // ignore non-local notifications
NavigationInfoSpec navInfo = new NavigationInfoSpec(); // send a blank one to remove
GBApplication.deviceService().onSetNavigationInfo(navInfo);
return true;
}
return false;
}
}

View File

@ -294,7 +294,8 @@ public class GBDeviceService implements DeviceService {
Intent intent = createIntent().setAction(ACTION_SETNAVIGATIONINFO) Intent intent = createIntent().setAction(ACTION_SETNAVIGATIONINFO)
.putExtra(EXTRA_NAVIGATION_INSTRUCTION, navigationInfoSpec.instruction) .putExtra(EXTRA_NAVIGATION_INSTRUCTION, navigationInfoSpec.instruction)
.putExtra(EXTRA_NAVIGATION_NEXT_ACTION, navigationInfoSpec.nextAction) .putExtra(EXTRA_NAVIGATION_NEXT_ACTION, navigationInfoSpec.nextAction)
.putExtra(EXTRA_NAVIGATION_DISTANCE_TO_TURN, navigationInfoSpec.distanceToTurn); .putExtra(EXTRA_NAVIGATION_DISTANCE_TO_TURN, navigationInfoSpec.distanceToTurn)
.putExtra(EXTRA_NAVIGATION_ETA, navigationInfoSpec.ETA);
invokeService(intent); invokeService(intent);
} }

View File

@ -114,6 +114,7 @@ public interface DeviceService extends EventHandler {
String EXTRA_NAVIGATION_INSTRUCTION = "navigation_instruction"; String EXTRA_NAVIGATION_INSTRUCTION = "navigation_instruction";
String EXTRA_NAVIGATION_DISTANCE_TO_TURN = "navigation_distance_to_turn"; String EXTRA_NAVIGATION_DISTANCE_TO_TURN = "navigation_distance_to_turn";
String EXTRA_NAVIGATION_NEXT_ACTION = "navigation_next_action"; String EXTRA_NAVIGATION_NEXT_ACTION = "navigation_next_action";
String EXTRA_NAVIGATION_ETA = "navigation_eta";
String EXTRA_APP_UUID = "app_uuid"; String EXTRA_APP_UUID = "app_uuid";
String EXTRA_APP_START = "app_start"; String EXTRA_APP_START = "app_start";
String EXTRA_APP_CONFIG = "app_config"; String EXTRA_APP_CONFIG = "app_config";

View File

@ -31,8 +31,12 @@ public class NavigationInfoSpec {
public static final int ACTION_OFFROUTE = 12; public static final int ACTION_OFFROUTE = 12;
public static final int ACTION_ROUNDABOUT_RIGHT = 13; public static final int ACTION_ROUNDABOUT_RIGHT = 13;
public static final int ACTION_ROUNDABOUT_LEFT = 14; public static final int ACTION_ROUNDABOUT_LEFT = 14;
public static final int ACTION_ROUNDABOUT_STRAIGHT = 15;
public static final int ACTION_FINISH = 16;
// ETA? Total Distance?
public String instruction; public String instruction;
public int distanceToTurn; public int distanceToTurn; ///< Distance to turn (in metres?)
public int nextAction; public int nextAction; ///< One of the ACTION_ constants
public String ETA; ///< Estimated time of Arrival
} }

View File

@ -186,6 +186,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUS
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NAVIGATION_DISTANCE_TO_TURN; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NAVIGATION_DISTANCE_TO_TURN;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NAVIGATION_INSTRUCTION; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NAVIGATION_INSTRUCTION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NAVIGATION_NEXT_ACTION; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NAVIGATION_NEXT_ACTION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NAVIGATION_ETA;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_ACTIONS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_ACTIONS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_BODY; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_BODY;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_DNDSUPPRESSED; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_DNDSUPPRESSED;
@ -890,6 +891,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
navigationInfoSpec.instruction = intent.getStringExtra(EXTRA_NAVIGATION_INSTRUCTION); navigationInfoSpec.instruction = intent.getStringExtra(EXTRA_NAVIGATION_INSTRUCTION);
navigationInfoSpec.nextAction = intent.getIntExtra(EXTRA_NAVIGATION_NEXT_ACTION,0); navigationInfoSpec.nextAction = intent.getIntExtra(EXTRA_NAVIGATION_NEXT_ACTION,0);
navigationInfoSpec.distanceToTurn = intent.getIntExtra(EXTRA_NAVIGATION_DISTANCE_TO_TURN,0); navigationInfoSpec.distanceToTurn = intent.getIntExtra(EXTRA_NAVIGATION_DISTANCE_TO_TURN,0);
navigationInfoSpec.ETA = intent.getStringExtra(EXTRA_NAVIGATION_ETA);
deviceSupport.onSetNavigationInfo(navigationInfoSpec); deviceSupport.onSetNavigationInfo(navigationInfoSpec);
break; break;
case ACTION_REQUEST_APPINFO: case ACTION_REQUEST_APPINFO:

View File

@ -116,6 +116,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NavigationInfoSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
@ -1526,4 +1527,26 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
} }
} }
@Override
public void onSetNavigationInfo(NavigationInfoSpec navigationInfoSpec) {
try {
JSONObject o = new JSONObject();
o.put("t", "nav");
if (navigationInfoSpec.instruction!=null)
o.put("instr", navigationInfoSpec.instruction);
o.put("distance", navigationInfoSpec.distanceToTurn);
String[] navActions = {
"","continue", "left", "left_sharp", "left_slight", "right", "right_slight",
"right_sharp", "keep_left", "keep_right", "uturn_left", "uturn_right",
"offroute", "roundabout_right", "roundabout_left", "roundabout_straight", "finish"};
if (navigationInfoSpec.nextAction>0 && navigationInfoSpec.nextAction<navActions.length)
o.put("action", navActions[navigationInfoSpec.nextAction]);
if (navigationInfoSpec.ETA!=null)
o.put("eta", navigationInfoSpec.ETA);
uartTxJSON("onSetNavigationInfo", o);
} catch (JSONException e) {
LOG.info("JSONException: " + e.getLocalizedMessage());
}
}
} }