Merge pull request #16645 from keymanapp/fix/android/16601-lastKnownKeyboard-state

fix(android): refresh current keyboard when resuming main activity
This commit is contained in:
Marc Durdin 2026-10-06 06:17:05 +02:00 • committed by GitHub
commit 7067caedb4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 30 deletions

View file

@ -437,17 +437,6 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
protected void onResume() {
super.onResume();
if (navigationView != null) {
updateCurrentKeyboardDrawerItemTitle(navigationView);
updateInstalledLanguagesDrawerTitle(navigationView);
initializeDrawerItemSubtitles(navigationView);
}
if (textView != null) {
// Reset inAppPredictionsSuspendedForSensitiveInput flag
KMManager.setPredictionsSuspended(textView.getInputType(), KeyboardType.KEYBOARD_TYPE_INAPP);
}
KMManager.onResume();
KMManager.hideSystemKeyboard();
@ -465,12 +454,35 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
}
resizeTextView(textView.isKeyboardVisible());
// The keyboard may have been changed while we were paused, for example if
// the keyboard picker activity is started.
com.keyman.engine.data.Keyboard currentKeyboard = KMManager.getCurrentKeyboardInfo(context);
if(currentKeyboard != null) {
// TODO(v20): eliminate `lastKnownKeyboardId` and always use `currentKeyboard.getKeyboardID()`
// TODO(v20): this lines up with onKeyboardChanged(), refactor accordingly
lastKnownKeyboardId = currentKeyboard.getKeyboardID();
}
if (navigationView != null) {
// TODO(v20): these three calls are repeated in various places and should be cleaned up
updateCurrentKeyboardDrawerItemTitle(navigationView);
updateInstalledLanguagesDrawerTitle(navigationView);
initializeDrawerItemSubtitles(navigationView);
}
if (textView != null) {
// Reset inAppPredictionsSuspendedForSensitiveInput flag
KMManager.setPredictionsSuspended(textView.getInputType(), KeyboardType.KEYBOARD_TYPE_INAPP);
textView.setTypeface(KMManager.getKeyboardTextFontTypeface(this));
}
KMManager.addKeyboardEventListener(this);
KMKeyboardDownloaderActivity.addKeyboardDownloadEventListener(this);
PackageActivity.addKeyboardDownloadEventListener(this);
CheckInstallReferrer.checkGooglePlayInstallReferrer(this, context);
// TODO(v20): move loadingIntentUri logic into a separate function
Intent intent = getIntent();
Uri loadingIntentUri = intent.getData();
@ -663,6 +675,9 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
if (drawerLayout.isDrawerOpen(GravityCompat.END)) {
drawerLayout.closeDrawer(GravityCompat.END);
} else {
updateCurrentKeyboardDrawerItemTitle(navigationView);
updateInstalledLanguagesDrawerTitle(navigationView);
initializeDrawerItemSubtitles(navigationView);
drawerLayout.openDrawer(GravityCompat.END);
}
return true;
@ -866,8 +881,9 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
* If URL is valid, download the kmp.
* @param packageUri URI to download the package.
* @param installMode KMP installation mode (silent, welcome only, or full)
* TODO: only ever pass packageId and bcp47 from callers, as KMPLink should be responsible for
* TODO(v20): only ever pass packageId and bcp47 from callers, as KMPLink should be responsible for
* URL parsing, not this function.
* TODO(v20): move this into a separate module
*/
public void downloadKMP(Uri packageUri, KmpInstallMode installMode) {
if (packageUri == null) {
@ -983,6 +999,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
overridePendingTransition(android.R.anim.fade_in, com.keyman.engine.R.anim.hold);
}
// TODO(v20): remove remaining tendrils
private void showWebBrowser() {
// Telemetry for in-app browser usage.
// Logging here because WebBrowserActivity is launched in a separate process.
@ -1267,7 +1284,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
}
}
// TODO: Move this to KMEA during Keyman 13.0 refactoring
// TODO(v20): Move this to KMEA during Keyman 13.0 refactoring
public static void useLocalKMP(Context context, Uri data) {
if (data != null) {
useLocalKMP(context, data, false);
@ -1410,6 +1427,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
});
}
// TODO(v20): cleanup setting draw item [sub]titles; lots of repetition and unnecessary conditions
private void initializeDrawerItemSubtitles(NavigationView navigationView) {
setDrawerItemSubtitle(navigationView, R.id.nav_spacebar_caption,
getString(R.string.drawer_subtitle_spacebar_caption));
@ -1417,8 +1435,6 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
getString(R.string.drawer_subtitle_show_osk));
setDrawerItemSubtitle(navigationView, R.id.nav_toggle_send_crash_report,
getString(R.string.drawer_subtitle_send_crash_report));
setDrawerItemSubtitle(navigationView, R.id.nav_about_current_keyboard,
getString(R.string.drawer_subtitle_about_current_keyboard));
updateThemeDrawerSubtitle(navigationView);
updateCurrentKeyboardDrawerSubtitle(navigationView);
}
@ -1632,6 +1648,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
}
}
// TODO(v20): remove
private void bindDrawerCheckboxAction(NavigationView navigationView, int menuItemId,
final Runnable onActivate) {
MenuItem menuItem = navigationView.getMenu().findItem(menuItemId);
@ -1671,6 +1688,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
});
}
// TODO(v20): remove
private void setDrawerCheckboxState(NavigationView navigationView, int menuItemId, boolean isChecked) {
MenuItem menuItem = navigationView.getMenu().findItem(menuItemId);
if (menuItem == null) {

View file

@ -2885,6 +2885,9 @@ public final class KMManager {
public static int getCurrentKeyboardIndex(Context context) {
String key = KMKeyboard.currentKeyboard();
if(key == null) {
return KeyboardController.INDEX_NOT_FOUND;
}
return KeyboardController.getInstance().getKeyboardIndex(key);
}
@ -2893,11 +2896,6 @@ public final class KMManager {
if(index < 0) {
// index can be undefined if user installs Keyman (without launching it)
// and then enables Keyaman as a system keyboard from the Android settings menus.
// We'll only log if key isn't for fallback keyboard
String key = KMKeyboard.currentKeyboard();
if (!isDefaultKey(key)) {
KMLog.LogError(TAG, "Failed getCurrentKeyboardIndex check for keyboard: " + key);
}
return null;
}
return KeyboardController.getInstance().getKeyboardInfo(index);

View file

@ -188,16 +188,15 @@ public class KeyboardController {
* If no match, returns INDEX_NOT_FOUND
* @param key - String of the key to find
* @return int - Index of the matching keyboard
*
* Note: do not perform logging here because KMLog.tagDebugInfo can call this, causing recursion
*/
public int getKeyboardIndex(String key) {
int index = INDEX_NOT_FOUND;
if (!isInitialized || list == null) {
KMLog.LogError(TAG, "getKeyboardIndex while KeyboardController() not initialized");
return index;
return INDEX_NOT_FOUND;
}
if (key == null || key.isEmpty()) {
KMLog.LogError(TAG, "getKeyboardIndex while key is null");
return index;
return INDEX_NOT_FOUND;
}
synchronized (list) {
@ -209,11 +208,7 @@ public class KeyboardController {
}
}
// We'll only log if key isn't for fallback keyboard
if (!KMManager.isDefaultKey(key)) {
KMLog.LogError(TAG, "getKeyboardIndex failed for key " + key);
}
return index;
return INDEX_NOT_FOUND;
}
/**

View file

@ -21,6 +21,7 @@ import io.sentry.Breadcrumb;
import io.sentry.Sentry;
import io.sentry.SentryLevel;
// TODO(v20): make KMLog more resilient to re-entrancy by preventing nested calls with a sentinel flag
public final class KMLog {
private static final String TAG = "KMLog";