BangleApps
Bangle.js App Loader (and Apps)
Install / Use
/learn @espruino/BangleAppsREADME
Bangle.js App Loader (and Apps)
- Try the release version at banglejs.com/apps
- Try the development version at espruino.github.io
The release version is manually refreshed with regular intervals while the development version is continuously updated as new code is committed to this repository.
All software (including apps) in this repository is MIT Licensed - see LICENSE By submitting code to this repository you confirm that you are happy with it being MIT licensed, and that it is not licensed in another way that would make this impossible.
How does it work?
- A list of apps is in
apps.json(this is auto-generated from all theapps/yourapp/metadata.jsonusing Jekyll orbin/create_apps_json.sh) - Each element references an app in
apps/<id>which is uploaded - When it starts, BangleAppLoader checks the JSON and compares it with the files it sees in the watch's storage.
- To upload an app, BangleAppLoader checks the files that are
listed in
apps.json, loads them, and sends them over Web Bluetooth.
Getting Started
Check out:
- Building your first Bangle.js Application
- Adding an app to the Bangle.js App Loader
- Customising the App Loader
What filenames are used
Filenames in storage are limited to 28 characters. To easily distinguish between file types, we use the following:
appid.infois JSON that describes an app - this is auto-generated by the App Loaderappid.imgis an imageappid.app.jsis JS code for applicationsappid.wid.jsis JS code for widgetsappid.clkinfo.jsis JS code for a clock infoappid.settings.jsis JS code for the settings menuappid.boot.jsis JS code that automatically gets run at boot timeappid.jsonis used for JSON settings for an app
Developing your own app
- Head over to the Web IDE and ensure
Save on Sendin settings set to the default setting ofTo RAM - We'd recommend that you start off using code from 'Example Applications' (below) to get started...
- Load
app.jsorwidget.jsinto the IDE and start developing. - The
Uploadbutton will load your app to Bangle.js temporarily
Adding your app to the menu
- Come up with a unique (all lowercase, no spaces) name, we'll assume
myappid. Bangle.js is limited to 28 char filenames and appends a file extension (eg.js) so please try and keep filenames short to avoid overflowing the buffer. - Create a folder called
apps/<id>, lets assumeapps/myappid - We'd recommend that you copy files from one of the Examples in
apps/_example_*(see below), or... apps/myappid/app.pngshould be a 48px icon- Use http://www.espruino.com/Image+Converter to create
apps/myappid/app-icon.js, using a 1 bit, 4 bit or 8 bit Web Palette "Image String" - Create/modify
apps/myappid/metadata.jsonas follows:
{ "id": "myappid",
"name": "My app's human readable name",
"shortName" : "Short Name",
"icon": "app.png",
"description": "A detailed description of my great app",
"tags": "",
"storage": [
{"name":"myappid.app.js","url":"app.js"},
{"name":"myappid.img","url":"app-icon.js","evaluate":true}
],
},
Screenshots
In the app metadata.json file you can add a list of screenshots with a line like: "screenshots" : [ { "url":"screenshot.png" } ],
To get a screenshot you can:
- Type
g.dump()in the left-hand side of the Web IDE when connected to a Bangle.js 2 - you can then right-click and save the image shown in the terminal (this only works on Bangle.js 2 - Bangle.js 1 is unable to read data back from the LCD controller). - Run your code in the emulator and use the screenshot button in the bottom right of the window.
You can also take multiple screenshots and use a website like this to turn it into an animated .gif file, and provide that instead in order to show motion in an app (flashing images, animations, etc).
Testing
For functional testing of apps using the Bangle.js emulator, see TESTING.md.
Online
This is the best way to test...
- Fork the https://github.com/espruino/BangleApps git repository
- Add your files
- Go to GitHub Settings and activate GitHub Pages
- Run your personal
Bangle App Loaderat https://<your-github-username>.github.io/BangleApps/index.html to load apps onto your device - Your apps should be inside it - if there are problems, check your web browser's 'developer console' for errors
Note: It's a great idea to get a local copy of the repository on your PC,
then run bin/sanitycheck.js - it'll run through a bunch of common issues
that there might be. To get the project running locally, you have to initialize and update the git submodules first: git submodule update --init.
Be aware of the delay between commits and updates on github.io - it can take a few minutes (and a 'hard refresh' of your browser) for changes to take effect.
Offline
Using the 'Storage' icon in the Web IDE (4 discs), upload your files into the places described in your JSON:
app-icon.js->myappid.img
Now load app.js up in the editor, and click the down-arrow to the bottom
right of the Send to Espruino icon. Click Storage and then either choose
myappid.app.js (if you'd uploaded your app previously), or New File
and then enter myappid.app.js as the name.
Now, clicking the Send to Espruino icon will load the app directly into
Espruino and will automatically run it.
When you upload code this way, your app will even be uploaded to Bangle.js's menu
without you having to use the Bangle App Loader
Note: Widgets need to be run inside a clock or app, so if you're
developing a widget you need to go go Settings -> Communications -> Load after saving
and set it to Load default application.
Example Applications
To make the process easier we've come up with some example applications that you can use as a base
when creating your own. Just come up with a unique name (ideally lowercase, under 20 chars), copy apps/_example_app
or apps/_example_widget to apps/myappid, and edit apps/myappid/metadata.json accordingly.
Note: the max filename length is 28 chars, so we suggest an app ID of under
20 so that when .app.js/etc gets added to the end the filename isn't cropped.
If you're making a widget please start the name with wid to make
it easy to find!
App Example
The app example is available in apps/_example_app
Apps are listed in the Bangle.js menu, accessible from a clock app via the middle button.
metadata.json- describes the app to bootloader and loaderapp.png- app icon - 48x48pxapp-icon.js- JS version of the icon (made with http://www.espruino.com/Image+Converter) for use in Bangle.js's menuapp.js- app codeChangeLog- A file containing a list of changes to your app so users can see what's changed
app-icon.js
The icon image and short description is used in Bangle.js's launcher.
Use the Espruino image converter and upload your app.png file.
Follow this steps to create a readable icon as image string.
- upload a 48x48 png file - THE IMAGE SHOULD BE 48x48 OR LESS
- set X Use Compression
- set X Transparency (optional)
- set Diffusion: flat
- set Colours: 1 bit, any of the Optimised options, or 8 bit Web Palette are best
- set Output as: Image String
Replace this line with the image converter output:
require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA=="))
Do not add a trailing semicolon
You can also use this converter for creating images you like to draw with g.drawImage() with your app.
Apps that need widgets can call Bangle.loadWidgets() once at startup to load
them, and then Bangle.drawWidgets() to draw them onto the screen whenever the app
has call to completely clear the screen. Widgets themselves will update as and when needed.
Widget Example
The widget example is available in apps/_example_widget
metadata.json- describes the widget to bootloader and loaderwidget.js- widget code
Widgets are just small bits of code that run whenever an app that supports them
calls Bangle.loadWidgets(). If they want to display something in the 24px high
widget bar at the top of the screen they can add themselves to the global
WIDGETS array with:
WIDGETS["mywidget"]={
area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right)
sortorder:0, // (Optional) determines order of widgets in the same corner
width: 24, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout
draw:draw // called to draw the widget
};
When the widget is to be drawn, x and y values are set up in WIDGETS["mywidget"]
and draw can then use this.x and this.y to figure out where it needs to draw to.
ChangeLog
This is a file containing a list of changes to your app so users can see what's changed, for example:
0.01: New App!
0.02: Changed the colors
0.03: Made the app run quicker
Entries should be newest last, with the version number of the last entry matching the version in metadata.json
Please keep the same format at the example as the file needs to
Related Skills
node-connect
342.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
85.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
342.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
342.5kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
