Skip to content

fix(notifications): use app language#20747

Open
david-allison wants to merge 1 commit intoankidroid:mainfrom
david-allison:19048-notification-language
Open

fix(notifications): use app language#20747
david-allison wants to merge 1 commit intoankidroid:mainfrom
david-allison:19048-notification-language

Conversation

@david-allison
Copy link
Copy Markdown
Member

Note

Assisted-by: Claude Opus 4.6 - withAppLocale + investigation

Purpose / Description

On API 32 and earlier, AppCompatDelegate.setApplicationLocales only works with AppCompatActivity.

Fixes

Approach

Work around this by manually setting the app locale

How Has This Been Tested?

Android Version = 7.0 (SDK 24)

  • Set the language to German then launch the app, before and after
Screenshot 2026-04-15 at 12 04 47 Screenshot 2026-04-15 at 12 03 44

Learning (optional, can help others)

https://developer.android.com/reference/androidx/appcompat/app/AppCompatDelegate#setApplicationLocales(androidx.core.os.LocaleListCompat)

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)
  • UI Changes: You have tested your change using the Google Accessibility Scanner

On API 32 and earlier, AppCompatDelegate.setApplicationLocales
 only works with AppCompatActivity.

Work around this by manually setting the app locale

Fixes 19048

Assisted-by: Claude Opus 4.6 - withAppLocale + investigation
Comment on lines 453 to +458
override fun onReceive(
context: Context,
rawContext: Context,
intent: Intent,
) {
// #19048: On API < 33, BroadcastReceiver context uses the system locale.
val context = rawContext.withAppLocale()
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm tempted to make an AnkiBroadcastReceiver which handles this automatically so people can't forget.

Thoughts?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not opposed! From a brief skim it seems there are other BroadcastReceivers in the codebase that do things like show themed toasts to the user, which are probably in the incorrect language right now, ex. this line in SharedDecksDownloadFragment can be called by a BroadcastReceiver's onReceive:

context?.let { showThemedToast(it, R.string.something_wrong, false) }

So it would be good to enforce this more uniformly.

@david-allison david-allison added this to the 2.24 release milestone Apr 15, 2026
Copy link
Copy Markdown
Member

@ericli3690 ericli3690 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you David!! This looks great. I'll make a note to test this on the new review reminders system too once our strings are localized.

Only one major concern: this issue was originally opened when I found this to-do comment by @mikehardy in NotificationChannels:

/**
 * Create or update all the notification channels for the app
 *
 * In Oreo and higher, you must create a channel for all notifications.
 * This will create the channel if it doesn't exist, or if it exists it will update the name.
 *
 * Note that once a channel is created, only the name may be changed as long as the application
 * is installed on the user device. All other settings are fully under user control.
 *
 * TODO should be called in response to [Intent.ACTION_LOCALE_CHANGED]
 * @param context the context for access to localized strings for channel names
 */
fun setupNotificationChannels(context: Context) {
// ...

In particular the TODO portion. Do we actually need to make setupNotificationChannels listen to Intent.ACTION_LOCALE_CHANGED, or will that no longer necessary after merging this PR? If so, please remove the above comment in NotificationChannels.

Comment on lines 453 to +458
override fun onReceive(
context: Context,
rawContext: Context,
intent: Intent,
) {
// #19048: On API < 33, BroadcastReceiver context uses the system locale.
val context = rawContext.withAppLocale()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not opposed! From a brief skim it seems there are other BroadcastReceivers in the codebase that do things like show themed toasts to the user, which are probably in the incorrect language right now, ex. this line in SharedDecksDownloadFragment can be called by a BroadcastReceiver's onReceive:

context?.let { showThemedToast(it, R.string.something_wrong, false) }

So it would be good to enforce this more uniformly.

Comment thread AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt
@david-allison
Copy link
Copy Markdown
Member Author

Thank you David!! This looks great. I'll make a note to test this on the new review reminders system too once our strings are localized.

Only one major concern: this issue was originally opened when I found this to-do comment by @mikehardy in NotificationChannels:

/**
 * Create or update all the notification channels for the app
 *
 * In Oreo and higher, you must create a channel for all notifications.
 * This will create the channel if it doesn't exist, or if it exists it will update the name.
 *
 * Note that once a channel is created, only the name may be changed as long as the application
 * is installed on the user device. All other settings are fully under user control.
 *
 * TODO should be called in response to [Intent.ACTION_LOCALE_CHANGED]
 * @param context the context for access to localized strings for channel names
 */
fun setupNotificationChannels(context: Context) {
// ...

In particular the TODO portion. Do we actually need to make setupNotificationChannels listen to Intent.ACTION_LOCALE_CHANGED, or will that no longer necessary after merging this PR? If so, please remove the above comment in NotificationChannels.

Untested, I suspect it will still be necessary

@mikehardy
Copy link
Copy Markdown
Member

If the goal is to have "all of the app" change when a language changes - either through our in-app language picker or through a system locale change, then you also must persist new notification channel names into the android system as well, implying that - yes - that notification channel setup needs to be hooked on to whatever infra we have for handling language updates, and we should be listening to system locale change broadcast

@david-allison david-allison added the Needs Author Reply Waiting for a reply from the original author label Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs Author Reply Waiting for a reply from the original author Needs Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Notification Doesn't Follow App Language

3 participants