If the main activity was paused, e.g. to open the keyboard picker, then
it would lost track of the last known keyboard, which meant that the
menu would show details for the wrong keyboard. Add resume logic to
refresh last known keyboard and as a side benefit, fix an unreported bug
with the text area font getting out of sync in the same way.
Also ensure that the keyboard data is updated before the drawer starts
to open, to prevent a delayed change to the active keyboard label.
As part of this, discovered a re-entrancy issue with KMLog, which would
try and collect debug data, which could itself trigger another KMLog
call. Did some basic cleanup of that, but more could be done in a future
iteration.
Noted a number of minor cleanup issues for resolution in v20. The API
has some assumptions around logging and use which should be tightened up
in a future release: in general, the API should not be logging invalid
parameters or state: it should return an error response to the caller,
which should be responsible for logging the issue, if it wants to. The
Engine should only log if there is something internally inconsistent.
Fixes: #16601
This PR provides two main services:
- It allows on-device KMP file providers (such as Chrome downloads or the local Files app) to smoothly pass those KMP files into Keyman for Android for installation.
- It also removes wildcard-host http / https deep-links from the app manifest, as these are invalid.
Fixes: #14854Fixes: #10133
Upon my investigation into related documentation, I've determined that with current versions of Android, setting up a general, "anywhere on the web" deep link for KMP files is not supported and should not be attempted.
How, then, do we facilitate external apps passing off KMP links or files to Keyman for Android? Turns out... we've already done the work for downloaded files with `file:` and `content:` scheme deep-links. The issue is that some of our permissions-checking code logic was bad. With a little work to correct them - removing the bad checks that never should have existed anyway - the files load nicely!
Build-bot: skip release:android
fix(android): show updates for lexical models
With this change the model info activity will show an available update to the lexical model.
PR partially drafted by AI (Gemini 3 Flash Preview).
Fixes: #16226
This change updates the Android Target API to 36 to satisfy the upcoming
annual Play Store Aug 31 requirement. It updates Keyman for Android to
use API level 36 by changing the compileSdk and targetSdkVersion
properties to 36.
Also update `compileSdkVersion` and some reformatting in `README.md`.
Changes made by AI (Gemini 3 Flash Preview).
Fixes: #16279
Build-bot: release:android
With this change the model info activity will show an available update
to the lexical model.
Commit partially drafted by AI (Gemini 3 Flash Preview).
Fixes: #16226
Build-bot: release:android
This is consistent with other version variables in build.gradle.
Encountered an issue with loading TIER.md with Android Studio Quail 1 |
2026.1.1 Patch 2 version, and this was an expedient workaround.
Test-bot: skip
PR #16146 introduced a problem with selecting a different font as
display font so that we always ended up with not setting the font.
This was caused by the font filenames now being a URL (which is necessary
because they get processed by the web engine). However, the Android code
checks for the existence of the font in order to create the typeface,
which only works for local paths.
This PR modifies and simplifies `KMKeyboard.getFontFilename` to return the
full path, renames `KMKeyboard.txtFont` and `KMKeyboard.oskFont` to make
it clearer that they contain a path and not a URL.
Also initialize `KMKeyboard.oskFontPath` with empty string instead of
`null`. This makes it consistent with` txtFontPath` and with the
documented behavior of `KMManager.getKeyboardOskFontFilename()` (which
returns `KMKeyboard.oskFontPath`).
Follows: #16146Fixes: #16187
Build-bot: release:android
This change moves to using `WebViewAssetLoader` for loading files from
the device instead of using file:// URLs. This fixes the blank keyboard
problem reported in #16096 for Android.
Also make `KMKeyboard.getKeyboardRoot()` private, and rename public
`Keyboard.getKeyboardPath()` to private `Keyboard.getKeyboardUrl()`.
Part-of: #16096