-
I did some more digging and found that the following steps will allow time sync to work:
- Select the watch and then 'Forget This Device' from the Bluetooth settings on the iPhone.
- From the web IDE using the WebBLE app, connect to the Bangle but do not pair.
- Enter
NRF.setServices({}, {cts: true})
into the console. - Disconnect from within the web IDE and reconnect, but this time pair with iOS and allow notifications.
After these steps it will update the boot code after switching between apps, and the time will then be synced. However, this only seems to last for one connection, and the whole process has to be done again if it's disconnected at all.
I tried adding that NRF.setServices line into boot.js for the ios app, but it did not seem to help.
- Select the watch and then 'Forget This Device' from the Bluetooth settings on the iPhone.
-
My time sync with iOS is not working either. It would appear CTS (Current Time Service) isn’t active on my phone because when I run ‘NRF.ctsGetTime()’ from the console it returns ‘Uncaught Error: CTS not active’.
I’m using webBLE to connect to the bangle if that helps narrow down the problem.
Thanks!
-
-
Yeah, I was using setClipRect as a mask essentially and layering the draws to create the animation.
const SCREEN_WIDTH = g.getWidth(); const SCREEN_HEIGHT = g.getHeight(); const BOX_HEIGHT = 50; const NUMBER_SIZE = 30; const ANIMATION_DURATION = 3000; const BOX_DIMENSIONS = { left: 0, top: SCREEN_HEIGHT / 2 - BOX_HEIGHT / 2, width: SCREEN_WIDTH, height: BOX_HEIGHT }; let numberValue = 0; let startTime = 0; let animationInterval; function setRect(method) { g[method](BOX_DIMENSIONS.left, BOX_DIMENSIONS.top, BOX_DIMENSIONS.width, BOX_DIMENSIONS.top + BOX_DIMENSIONS.height); } function drawNumber(yPosition, color) { g.setColor(color); g.setFont("Vector", NUMBER_SIZE); g.drawString(numberValue.toString(), SCREEN_WIDTH / 2 - g.stringWidth(numberValue.toString()) / 2, yPosition); } function animateNumber() { const now = Date.now(); const progress = Math.min(1, (now - startTime) / ANIMATION_DURATION); g.clear(); const currentY = (SCREEN_HEIGHT - NUMBER_SIZE) * progress; drawNumber(currentY, g.theme.fg); setRect('fillRect'); setRect('setClipRect'); drawNumber(currentY, g.theme.bg); g.setClipRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); g.flip(); if (progress < 1) { animationInterval = setTimeout(animateNumber, 1000 / 60); } else { numberValue = Math.floor(Math.random() * 100); startTime = Date.now(); animationInterval = setTimeout(animateNumber, 500); } } startTime = Date.now(); animateNumber();
But it sounds like extending drawImages like you said could be way more versatile.
-
-
Just chiming in about a similar issue I’ve experienced with my Bangle 2s. Both of my watches consistently display two identical scheduler apps in the ‘Installed’ section of the app loader, similar to what Tev described. Even after all the factory resets and firmware upgrades I’ve performed, these duplicate apps persist. Initially, I thought this was normal and speculated there could be a reason for having two of the same app.
-
-
-
-
It also works for starting apps or running code on your bangle by creating a new task in Tasker and adding a "System" action called "Send Intent" and then fill it out following Gordon's guide here for sending intents from Android -> Bangle.
I think this capability is amazing to have on the Bangle and just wanted to share in case others weren't aware or hadn't tried using intents yet like me.
-
Right now I'm using a combination of Light Switch with tap side to unlock and then pattern launcher to launch this new
gassist
app. Combined with Tasker, Google Routines, and Smart Lock on the Android phone it's actually a fairly seamless experience already. But a system wide way to initiate it on the Bangle might be convenient.In order for Google Assistant to use Tasker we need give it the "Write Secure Settings" permission through ADB that can be granted or revoked with a helper app on a PC from the main dev of Tasker here.
Google Routines needs to be configured with the starters and actions. For me this is done by opening the
Google
app > profile pic > "Settings" > "Google Assistant" > "Routines".Starter is the word or phrase that initiates the task. Action should contain "Run" or "Start" followed by the name of the task in Tasker followed by "in" or "with" + "tasker".
The Smart Lock can be configured on Android so you don't have to unlock your device when you tell it to start a task.
I have it drafted up in a new branch right now and can do a PR if anyone else will find it useful.
-
Do you think this is worth putting on the app loader?
All it does is start Google Assistant's voice prompt on the phone, but I think it could be convenient for certain scenarios like starting navigation or playing a certain song. Especially when combined with apps like Tasker and the"Navigate In Google Maps With Voice" task that asks for a destination and starts navigation all in one go.
Maybe it could have a way to activate it in the background from anywhere, like the tap side feature from Light Switch. Or maybe if combined with Tasker it could send intents (set up beforehand) to the watch using the voice prompt that was initiated from the watch, essentially giving you hands free control of the Bangle.
-
-
I'm trying to make a super simple app that only sends an android intent over bluetooth and then goes to the clock app.
When uploading to RAM it works as expected, but if I save it to storage as an app and run it from the launcher or Pattern Launcher I get the "Loading..." box in the middle of the screen and it never goes back to the clock app.
Bluetooth.println(""); Bluetooth.println(JSON.stringify({ t:"intent", target:"activity", action:"android.intent.action.VOICE_COMMAND", flags:["FLAG_ACTIVITY_NEW_TASK"] })); Bangle.showClock();
-
-
The only thing I've noticed is Google maps is very persistent in sending new nav messages while using it, so messages always tries to open these up if you are on the clock or in the launcher.
At one point I thought it was working where if you were actively using navigation you could tap on the display to transition back to the clock and it would stay there until you hit the flashing nav icon in the widget bar to get back to the nav message gui.
-
Oh, I forgot to mention it also handles the navigation messages from Google maps, which after Gordon's latest fixes works fantastic and is a killer feature to have when traveling around.
And I suppose it's possible the android app is required to establish more than just a simple Bluetooth connection with gadgetbridge.
-
Hi, I just tried your code and it showed up once in the phone when connected to gadgetbridge like you said. However, when checking the log it does show multiple presses. So it does seem to be receiving them from the bangle, just not showing them in Android every time.
I believe you only need the Android app for getting notifications, music control, find my phone, alarm syncing, battery status syncing, or forwarding your phones gps to the bangle. For Bluetooth print line you shouldn't need it, but I could be wrong.
-
Thanks, Gordon.
And that does sound a lot simpler and eliminates the need to convert units, maintain settings, follow regional variances, as well as variations in whether you're walking, biking, driving, on the train/bus... Letting all of that be handled by maps itself seems to make the most sense in all cases.
-
Yes, you're right. I completely understand that it will be different for everyone, and it's not an issue for me to maintain my own custom locale file either.
Why does that have to match the maps app exactly?
When I'm driving having the watch start showing feet at 1 mile is a little unusual, and they change in 0.1 mi increments because that is how maps sends it (presumably as 160.9344 meters?) until it reaches 500ft.
-
-
Great, that was fast!
There was just one other thing that may need to be implemented yet. Formatting the distance to match what maps shows.
In my case it starts showing miles with 1 decimal place at less than 10 miles and switches to 500 feet after 0.1 miles.
This is how the distance is currently formatted in the
locale
file on the watch. This starts showing feet at < 1 mile.distance:(n,dp)=> n<1609.34?round(n/0.3048,dp)+"ft":round(n/1609.34,dp)+"mi",speed
And this is how it needs to be configured in my case for it to closer match the distance formatting of maps.
distance: (n) => { var miles = n / 1609.34; var dp = miles < 10 ? 1 : 0; return n < 152.4 ? Math.round(n * 3.28084) + "ft" : (miles < 10 ? miles.toFixed(1) : Math.round(miles)) + "mi"; },
So we will need to figure out a way to properly format the distance values based on the users locale. Can this be added to the interface.html of locale?
-
Were you able to get icons for those?
I didn't get the icons for the lane indicators but I did snag some screenshots on my phone. We'll have to scrape/parse this other icon container too. It's also used to display the turn coming up next I believe.
For the names, an example I noticed was like this below where Main St flows into Centerpoint Dr after it divides into one way streets but it is also an alternate route for the interstate. So it's one road sharing names, most likely this is an edge case.
Main St / I-29 ALT / Centerpoint Dr
-
I was able to test the navigation out using a nightly build with the newest fixes and the feet work correctly now except for a very minor rounding error where the watch will show 49ft instead of 50ft for example. Besides that it works very well now.
The roundabout also works but will need to reflect which side of the road we drive on and maybe a little more dithering or removal of the opposite side of the roundabout that wasn't used to make it easier to distinguish the path.
I also was able to grab some of the new icon images after I remembered to turn logging back on. I missed a few others before that.
00000000000000000000000000000000 00000000000000000000011100000000 00000000000000000011111111100000 00000000000000000111111111110000 00000000000000001111000001111000 00000000000000001110000000111100 00000000000000011100000000011100 00000000000000011100001000001100 00000000000000011000011100001110 00000000000000011000011110001110 00000000000000011000011100001110 00000000000000011100000000001100 00000000000000011100000000011100 00000000000000001110000000011100 00000000000000001110000000111000 00000111100011000111000000111000 00000111100011100111000001110000 00000111111111100011100011110000 00001111111111110011110011100000 00001111111111111001110111000000 00001111100011111000111110000000 00011111100011111100011110000000 00011111100011111100011100000000 00011111111111111110001000000000 00111111111111111110000000000000 00111111100011111110000000000000 00111111100011111111000000000000 01111111100011111111000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000001111110000000000 00000000000000111111111100000000 00000000000001111111111110000000 00000000000011111000111111000000 00000000000111100000001111100000 00000000001111000000000111100000 00000000001111000000000011110000 00000000001110000000000011110000 00000000001110000000000001110000 00000000001110000000000001110000 00000000001110000000000001110000 00001100001110001100000001110000 00011110001110011110000001110000 00001111001110111110000001110000 00001111101111111100000001110000 00000111111111111000000001110000 00000011111111110000000001110000 00000001111111100000000001110000 00000000111111000000000001110000 00000000001110000000000001110000 00000000001100000000000001110000 00000000000000000000000001110000 00000000000000000000000001110000 00000000000000000000000001110000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000001000000000000000 00000000000000011100000000000000 00000000000001111110000000000000 00000000000001111111000000000000 00000000000011111111100000000000 00000000001111111111110000000000 00000000011111011111111000000000 00000000011110011101111100000000 00000000111100011100111100000000 00000000011000011100011000000000 00000000000000011100000000000000 00000000000000011100000000000000 00000000000000011110000000000000 00000000000000011110000000000000 00000000000000011111000000000000 00000000000000001111100000000000 00000000000000000111110000000000 00000000000000000011111000000000 00000000000000000001111000000000 00000000000000000000111100000000 00000000000000000000011100000000 00000000000000000000011110000000 00000000000000000000001110000000 00000000000000000000001110000000 00000000000000000000001110000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000001111111000000000000 00000000000011111111110000000000 00000000000111111111110000000000 00000000001111100001111000000000 00000000001111000000111100000000 00000000011110000000111100000000 00000000011110000000011100000000 00000000011110000000011100000000 00000000011110000000111100000000 00000000001111000000111100000000 00000000001111100001111000000000 00000000000111110011110000000000 00000000000011110011110000000000 00000000000011110010000000000000 00000000000011110000000000000000 00000001100011110001100000000000 00000011110011110011110000000000 00000001111011110111110000000000 00000000111111111111100000000000 00000000011111111111000000000000 00000000001111111110100000000000 00000000000111111101100000000000 00000000000011111011100000000000 00000000000001110011100000000000 00000000000000100011100000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 // My attempt at mirroring them "LHD": [ "00000000000000000000000000000000", "00000000111000000000000000000000", "00000111111111000000000000000000", "00001111111111100000000000000000", "00011110000011110000000000000000", "00111100000001110000000000000000", "00111000000000111000000000000000", "00110000010000111000000000000000", "01110000111000011000000000000000", "01110001111000011000000000000000", "01110000111000011000000000000000", "00110000000000111000000000000000", "00111000000000111000000000000000", "00111000000001110000000000000000", "00011100000001110000000000000000", "00011100000011100011000111100000", "00001110000011100111000111100000", "00001111000111000111111111100000", "00000111001111001111111111110000", "00000011101110011111111111110000", "00000001111100011111000111110000", "00000001111000111111000111111000", "00000000111000111111000111111000", "00000000010001111111111111111000", "00000000000001111111111111111100", "00000000000001111111000111111100", "00000000000011111111000111111100", "00000000000011111111000111111110", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000001111110000000000000000", "00000000111111111100000000000000", "00000001111111111110000000000000", "00000011111100011111000000000000", "00000111110000000111100000000000", "00000111100000000011110000000000", "00001111000000000011110000000000", "00001111000000000001110000000000", "00001110000000000001110000000000", "00001110000000000001110000000000", "00001110000000000001110000000000", "00001110000000110001110000110000", "00001110000001111001110001111000", "00001110000001111101110011110000", "00001110000000111111110111110000", "00001110000000011111111111100000", "00001110000000001111111111000000", "00001110000000000111111110000000", "00001110000000000011111100000000", "00001110000000000001110000000000", "00001110000000000000110000000000", "00001110000000000000000000000000", "00001110000000000000000000000000", "00001110000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000010000000000000000", "00000000000000111000000000000000", "00000000000001111110000000000000", "00000000000011111110000000000000", "00000000000111111111000000000000", "00000000001111111111110000000000", "00000000011111111011111000000000", "00000000111110111001111000000000", "00000000111100111000111100000000", "00000000011000111000011000000000", "00000000000000111000000000000000", "00000000000000111000000000000000", "00000000000001111000000000000000", "00000000000001111000000000000000", "00000000000011111000000000000000", "00000000000111110000000000000000", "00000000001111100000000000000000", "00000000011111000000000000000000", "00000000011110000000000000000000", "00000000111100000000000000000000", "00000000111000000000000000000000", "00000001111000000000000000000000", "00000001110000000000000000000000", "00000001110000000000000000000000", "00000001110000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000011111110000000000000", "00000000001111111111000000000000", "00000000001111111111100000000000", "00000000011110000111110000000000", "00000000111100000011110000000000", "00000000111100000001111000000000", "00000000111000000001111000000000", "00000000111000000001111000000000", "00000000111100000001111000000000", "00000000111100000011110000000000", "00000000011110000111110000000000", "00000000001111001111100000000000", "00000000001111001111000000000000", "00000000000001001111000000000000", "00000000000000001111000000000000", "00000000000110001111000110000000", "00000000001111001111001111000000", "00000000001111101111011110000000", "00000000000111111111111100000000", "00000000000011111111111000000000", "00000000000101111111110000000000", "00000000000110111111100000000000", "00000000000111011111000000000000", "00000000000111001110000000000000", "00000000000111000100000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000010000000000000000", "00000000000000111000000000000000", "00000000000001111110000000000000", "00000000000011111110000000000000", "00000000000111111111000000000000", "00000000001111111111110000000000", "00000000011111111011111000000000", "00000000111110111001111000000000", "00000000111100111000111100000000", "00000000011000111000011000000000", "00000000000000111000000000000000", "00000000000000111000000000000000", "00000000000001111000000000000000", "00000000000001111000000000000000", "00000000000011111000000000000000", "00000000000111110000000000000000", "00000000001111100000000000000000", "00000000011111000000000000000000", "00000000011110000000000000000000", "00000000111100000000000000000000", "00000000111000000000000000000000", "00000001111000000000000000000000", "00000001110000000000000000000000", "00000001110000000000000000000000", "00000001110000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000" };
A couple things I noticed:
- There are lane indicator icons that show you what lane you should be in next for roundabouts and exits, it would be really useful to be able to see those as well, even if it is just briefly.
- Long street names or multiple road names that are combined into one overflow the width of the screen. Is there a certain way this should be handled? Right now they are combined with
/
and sometimes a single road can have 3 names combined which can be quite lengthy
Everything else seems to work great as far as I can tell.
- There are lane indicator icons that show you what lane you should be in next for roundabouts and exits, it would be really useful to be able to see those as well, even if it is just briefly.
No, I don't think it ever worked for me previously.
I can confirm this newest version works though. Thank you!