Building for Android
A Tessel app can be built as an Android app from the same code: the views,
state, timers, await and the rest work as they do on a computer. This
page covers what to install, how to build and try an app, how it behaves on
a phone, and how to make the package Google Play takes.
Android support is new. Read What doesn’t work yet before planning an app around it.
What you need
Section titled “What you need”Tessel compiles the app itself. Putting it in a package uses Android’s own tools, so they have to be installed:
- the Android SDK, with its build tools and a platform;
- the Android NDK;
- a JDK (Java), which signs packages and compiles the small Java part every Android app has. A Java runtime alone isn’t enough.
The simplest way to get all three is to install
Android Studio, then open its SDK
Manager and add the NDK. Without Android Studio, Google’s sdkmanager
installs the same parts:
sdkmanager "platform-tools" "platforms;android-36" "build-tools;36.0.0" "ndk;28.2.13676358"Tessel looks for the SDK in the usual place for your system, or in the
folder ANDROID_HOME names. To see what it found, run:
tessel android doctorBuilding Android apps (`tessel build --android`) needs: ok Android SDK: /Users/ada/Library/Android/sdk ok build tools: /Users/ada/Library/Android/sdk/build-tools/36.0.0 ok platform: Android API 36 (…/platforms/android-36/android.jar) ok NDK: …/ndk/28.2.13676358/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang ok Java: /opt/homebrew/opt/openjdk@17/bin/java later Tessel's runtime for Android: the first Android build downloads it (about 50 MB)To run an app: ok connected: emulator-5554; install with `adb install -r <app>.apk`Everything needed to build is here.Anything missing is listed with the command that installs it.
Tessel’s own part for Android isn’t in the package you installed, since most people never need it. The first Android build downloads it (about 50 MB), once for each version of Tessel.
Building and trying an app
Section titled “Building and trying an app”tessel build counter.tsl --androidbuilt counter.apkThat’s an .apk: a package you can install on a phone or an emulator. With
one connected (tessel android doctor says so), install and start it with
Android’s adb:
adb install -r counter.apkThe app is then in the phone’s app list, under its name.
What the app prints with print goes to the phone’s log, which you can
watch from your computer:
adb logcat -s tesselThe app’s name, id, version and icon come from
tessel.toml and icon.png, as for other builds. Two
things to know:
- The id names the app on the phone and in Google Play, and can never
change once the app is published. Set it yourself, like
id = "com.example.tally": at least two parts, each starting with a letter. (A-in it becomes_, which is what Android allows.) - The version must go up with every update you publish. Android compares
versions by a number, which Tessel works out from
version(1.4.2becomes 1004002), or takes frombuildif that’s a whole number.
Apps run on Android 11 and later, on phones and tablets with 64-bit ARM processors (which is all that Google Play’s current rules allow new apps to require).
How an app behaves on a phone
Section titled “How an app behaves on a phone”The window is the whole screen; the width: and height: of the app are
ignored. Beyond that:
- Touch. A tap is a click. Dragging inside a
Scroll(or a list, or a code editor) scrolls it, and it keeps moving for a moment when you let go. Sliders and views with.onDragare dragged as with a mouse. - Long press. Holding a finger on a view opens its
.contextMenu, as a right click does. Menus are drawn larger than on a computer, for fingers. - Pinch. Two fingers moving apart or together reach a view’s
.onPointeras a pinch, as on a trackpad. - The system’s bars. The app is laid out between the status bar at the top and the navigation bar at the bottom, and clear of a camera cutout.
- The keyboard. Tapping a text field brings up the on-screen keyboard,
with its suggestions, corrections, swipe typing and emoji. The layout
shrinks to the space above the keyboard, and a field in a
Scrollis scrolled into view if the keyboard would cover it. Asecurefield is typed as a password, and a code editor without corrections. - Dialogs and the clipboard.
alertandconfirmare the system’s dialogs, andcopyToClipboardandclipboardTextuse the phone’s clipboard. If the user leaves the app while aconfirmis open, it’s answeredfalse. - Back. The Back button (or gesture) closes what’s on top: a sheet or popover, an open menu, the keyboard. With nothing open, it leaves the app, which keeps running in the background.
- Dark theme. An app follows the phone’s theme, and changes with it
while running.
app Name(appearance: .dark)(or.light) keeps one. - Rotation. The app is laid out again for the new shape.
- In the background. The app keeps its
statewhile it’s in the background. If the system ends it to free memory, it starts fresh the next time, so save what matters when it changes, not when the app closes.
Relative file paths are in the app’s own private folder, the only place an Android app may write freely.
Design for a narrow screen: a row of five buttons that fits a desktop window
doesn’t fit a phone. HStacks that may be too wide can go in a Scroll, or
be VStacks.
What doesn’t work yet
Section titled “What doesn’t work yet”- Choosing files.
openFile,openFiles,saveFileandchooseFoldergive no file. Android’s file chooser is a screen of its own that the app has to step aside for, and these functions wait for their answer on the spot; the two don’t fit together yet. Keep an app’s files in its own folder (relative paths, orappDataFolder). - Corrections of earlier words. The keyboard corrects the word being typed. It can’t go back and change words typed before, as it can in Android’s own text fields.
- Extra windows (
Window) and printing aren’t available. - Menu bars and ribbons are drawn, but they’re designed for a wide window and a mouse. On a phone, prefer buttons and context menus.
- Pinch was written but couldn’t be tried: the emulator Tessel is tested on has no second finger.
- Everything here was tested on an emulator, building from macOS. A real phone, and building from Windows, haven’t been tried.
Publishing on Google Play
Section titled “Publishing on Google Play”Google Play takes an app bundle (.aab), signed with a key of your own.
1. Make a key, once, and keep it safe: every update of the app must be signed with the same key.
keytool -genkeypair -keystore upload.jks -alias upload -keyalg RSA -keysize 2048 -validity 10000It asks for a password and a few details. (keytool comes with the JDK.)
Don’t put the keystore in a public repository.
2. Name the key in tessel.toml:
[app]name = "Tally"id = "com.example.tally"version = "1.0.0"
[android]keystore = "upload.jks"key = "upload"keystore is a path relative to tessel.toml, and key is the alias given
to keytool.
3. Build the bundle, with the keystore’s password in the environment
(passwords never go in tessel.toml):
TESSEL_ANDROID_KEYSTORE_PASSWORD='…' tessel build . --android --bundlebuilt tally.aabIf the key has a different password from the keystore, set
TESSEL_ANDROID_KEY_PASSWORD too.
4. Upload the .aab in the Google Play Console.
The first time, Play asks you to enrol in Play App Signing; the key you made
is then your upload key.
With [android] in tessel.toml, tessel build --android signs the .apk
with your key too. Without it, packages are signed with Android’s debug
key: fine for trying the app, but Google Play doesn’t take them.