Status Update
Comments
al...@google.com <al...@google.com>
ri...@google.com <ri...@google.com> #2
Please help us out! If you are planning to work on this issue within the next year, please reply indicating the timeline you intend to complete the work and remove the "Android Blintz Close Candidate" hotlist. If it is expected for this issue to take multiple years to resolve, please add it to the android_icebox hotlist (
Stale issues that aren't removed from the "Android Blintz Close Candidate" will be closed in 7 days, so if you think this should be closed there's no need to do anything. For more information please see go/android-blintz.
If you are not the assignee of this bug, and feel this issue needs to be escalated, please email the components default assignee with the bug number, and what you'd like to escalate.
ri...@google.com <ri...@google.com> #3
For more information please see go/android-blintz.
jo...@gmail.com <jo...@gmail.com> #4
For more information please see go/android-blintz.
pr...@google.com <pr...@google.com> #5
Tagging with a review tag so that Jetpad picks it up
[LIBRARY_API_REVIEW_TAG:core/core/api/1.4.0-alpha01.txt]
ki...@gmail.com <ki...@gmail.com> #6
"Please add."?
se...@gmail.com <se...@gmail.com> #7
Oh, okay -- it's a feature request to add that method.
go...@google.com <go...@google.com>
ya...@gmail.com <ya...@gmail.com> #8
Handler.hasCallbacks was added in JB timeframe in
It was marked as @hide, so technically we can use reflection on pre-29 versions to get to it. But what would we do ICS? Nothing?
ly...@gmail.com <ly...@gmail.com> #9
And on ICS there is no underlying MessageQueue API to check for runnable callbacks. That was added as part of the same original CL at
Note that we didn't see a single internal or external request to actually expose this API in AndroidX in a backwards compatible way.
sh...@gmail.com <sh...@gmail.com> #10
It would have to be RequiresApi(JELLY_BEAN)
, but if the @hide
method was on the non-SDK-usage blacklist in P then we're out of luck.
so...@gmail.com <so...@gmail.com> #11
Where do I find that blacklist?
ba...@gmail.com <ba...@gmail.com> #12
You could either check the status manually by searching in a CSV (SDK 29) and TXT (SDK 28):
Or go ahead and write it and then pass the library through veridex
:
go...@google.com <go...@google.com>
po...@gmail.com <po...@gmail.com> #13
It's light-greylist on SDK 28, so we should be able to reflect on SDK 16+.
ma...@zentity.com <ma...@zentity.com> #14
Though if an OEM changed the implementation, we're going to have to throw an exception. It's unlikely, but it's there.
de...@workerbase.com <de...@workerbase.com> #15
Still waiting on core
to go back to alpha... This is waiting in aosp/1580773.
as...@google.com <as...@google.com> #16
Branch: androidx-main
commit 7e9c4bfcbd0a3bebc25ec4747922bcf80cd278fe
Author: Alan Viverette <alanv@google.com>
Date: Mon Feb 08 17:41:41 2021
Add compat method for Handler.hasCallbacks()
Fixes UnsafeNewApiCall errors, fixes APIs that were incorrectly targeting
API 16, improves exception logging. Cleans up test formatting.
Relnote: "Adds Handler.hasCallbacks() method for parity with platform SDK"
Fixes: 113855676
Test: HandlerCompatTest#testHasCallbacks, HandlerCompatTest
Change-Id: Idce1c9fbe0d93bd9ebcb26716a63834bb1c4c12d
M core/core/api/current.txt
M core/core/api/public_plus_experimental_current.txt
M core/core/api/restricted_current.txt
M core/core/src/androidTest/java/androidx/core/os/HandlerCompatTest.java
M core/core/src/main/java/androidx/core/os/HandlerCompat.java
as...@google.com <as...@google.com> #17
Hey all, we added text like this to the
For backward compatibility with previous Android versions, equivalent APIs are also available in AndroidX. However, the backward compatible APIs work with the AppCompatActivity context, not the application context, for Android 12 (API level 32) and earlier. Access the backward compatible APIs with Appcompat 1.6.0 or higher.
se...@gmail.com <se...@gmail.com> #18
I would suggest at least adding to the documentation about the attachBaseContext()
required in Application.kt, Services, activities that do not extend AppCompatActivity, etc. And a suggested implementation or gist would be very useful too.
This documentation could be added beneath, or as part of
Such as...
Application Context in Android 12 and lower
In order for application context to have the correct language resources, developers will need to handle attachBaseContext()
in Application.kt, Services, activities that do not extend AppCompatActivity (TODO: Where else is this needed???). The following code snippet shows how this may be implemented:
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(getContextForLanguage(base));
}
public static Context getContextForLanguage(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) return context;
String languageTag = PreferenceManager.getDefaultSharedPreferences(context).getString(PREF_APP_LANGUAGE_TAG, "");
if (languageTag.isEmpty()) return context;
Locale locale = Locale.forLanguageTag(languageTag);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
configuration.setLocales(new LocaleList(locale));
} else {
configuration.setLocale(locale);
}
return context.createConfigurationContext(configuration);
}
I'm not sure if this is the best implementation, but it has worked very well for our app with ~5m downloads (and supported in 22 languages). I think many developers are avoiding adding an in-app language picker for Android 12 and under due to the amount of testing and lack of documentation that increases the risk trying to find the correct implementation.
Thanks!
do...@gmail.com <do...@gmail.com> #19
ch...@gmail.com <ch...@gmail.com> #20
I would also like to point out that when setting locale to Traditional Chinese for Android 6 (not tested on earlier Android versions from KitKat to Lollipop), the following codes do not work even for Activity Context:
AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Locale.TRADITIONAL_CHINESE))
AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Locale.TAIWAN))
AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Locale("zh", "TW")))
AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Locale("zh_tw")))
The following works for Android 6:
AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Locale("zh-tw")))
as...@google.com <as...@google.com> #21
Hi
ca...@google.com <ca...@google.com> #22
We added new API (
Feel free to try it and let us know if there is any issue.
Here is the release note:
se...@gmail.com <se...@gmail.com> #23
Thanks! I just tested this and works great... on a side-note Services also need this added in attachBaseContext()
otherwise they can have the wrong context for notifications, strings, etc.
I didn't see any issues with upgrading users who have already selected a different language either - their context/strings looked correct with Application context 👍
se...@gmail.com <se...@gmail.com> #24
One issue I've found with ContextCompat.getContextForLanguage()
is that it doesn't update the default Locale - Locale.getDefault()
.
This can prove problematic in Application/Service classes, as well as it isn't inline with the other changes with language changes in AppCompatActivity
or in API 33+, which both adjust the Locale.getDefault()
to the users selected language.
I believe the default Locale should be updated similarly as done in AppCompatActivity/API 33+, no?
ca...@google.com <ca...@google.com> #25
Hi,
Thanks for your feedback. I agree that adding Locale.getDefault()
to ContextCompat.getContextForLanguage()
would help some developers who are not aware that Locale
is still not updated in other Android components. However, it doesn't make much sense from an API perspective. If someone just wants to get the context via ContextCompat.getContextForLanguage()
, they may not be aware that an unrelated object (Locale
) has also been changed. It looks fine in per-app locales cases for now, but we don't want someone to use this API to cause unexpected behavior someday. I think we can add some description in the docs to help other developers aware this so that app owners can add Locale.setDefault()
themselves.
se...@gmail.com <se...@gmail.com> #26
Good point, it doesn't make sense to set the default Locale in ContextCompat.getContextForLanguage()
. When you update its docs can you state that the per-app locale can be retrieved with LocaleManagerCompat.getApplicationLocales() outside of activity context to set default Locale with?
Otherwise I think developers are going to try to use AppCompatDelegate.getApplicationLocales() and not know there's another similar API...
ca...@google.com <ca...@google.com> #27
Thanks, I'll update it in the docs. If you want to set per-app locale to Locale
after ContextCompat.getContextForLanguage()
, you can consider getting per-app locale from Context
, which returns from ContextCompat.getContextForLanguage()
because its configuration already contains per-app locale and you can save one disk IO.
se...@gmail.com <se...@gmail.com> #28
Right, using LocaleManagerCompat.getApplicationLocales()
would lead to an extra disk IO.
So, basically an in-app implementation of this could be...
Context updatedContext = ContextCompat.getContextForLanguage(initialContext);
Locale updatedLocale = updatedContext.getResources().getConfiguration().locale; // using deprecated for example only
// Avoid setting default locale needlessly
if (!Locale.getDefault().equals(updatedLocale)) {
Locale.setDefault(updatedLocale);
}
return updatedContext;
Thanks!
[Deleted User] <[Deleted User]> #29
Using ContextCompat.getContextForLanguage(context)
and setting the base context in the Application
works great for the use case when the app is restarted. The problem we have is when we update the locale programmatically in the app with AppCompatDelegate
.
We are using the application context to retrieve strings across the whole app.
How can we make sure that this application context is using the app locale under the hood without restarting the whole application?
se...@gmail.com <se...@gmail.com> #30
I just opened another issue for per-app languages (affects Android 12 and under too):
[Deleted User] <[Deleted User]> #31
E.g.
- The user has configured multi-profile and when the application is launched multi-profile screen displays there are 3 user logins and each has a different locale, once any user is selected related locale should be set. For activity, it is working correctly but with the application context below Android 12, it picks the device locale for the application context string.
- For the same scenario, if a user selects the first user and then navigates to the second user then the application locale should also be refreshed.
Please suggest a solution or way to fix it otherwise it is difficult to migrate.
sh...@miniclip.com <sh...@miniclip.com> #32
ch...@beyls.net <ch...@beyls.net> #33
The current implementation of ContextCompat.getContextForLanguage(context)
has some major issues that make it hard to recommend:
- Each call performs a blocking disk I/O call which impacts performance, because
LocaleManagerCompat.getApplicationLocales(context)
(used internally) performs a disk I/O.ContextCompat.getString(context, resId)
suffers from the same issue because it callsContextCompat.getContextForLanguage(context)
internally. - The documentation suggests to call it in Application's
attachBaseContext()
, in which case a single I/O call would be acceptable. However, if the selected language is updated while the application is open, the Application context language will not be updated, so this technique doesn't work properly.
I suggest to implement some synchronized caching mechanism in AppLocalesStorageHelper
, similar to what AppCompatDelegate
does. This way, there should only be a single blocking disk I/O during the first call to ContextCompat.getContextForLanguage(context)
, and it can then be called repeatedly everywhere an Activity Context is not available.
The documentation should also be updated to mention the big limitation of calling ContextCompat.getContextForLanguage(context)
in Application's attachBaseContext()
.
As a workaround, I reimplemented ContextCompat.getContextForLanguage(context)
to use a cache internally that I also update when calling AppCompatDelegate.setApplicationLocales()
, but since that cache is not synchronized with AppCompatDelegate
's cache I get 2 blocking I/O reads in total.
ch...@gmail.com <ch...@gmail.com> #34
Any updates on issue described in the comment above?
Description
Version used: 1.6.0-beta01
Devices/Android versions reproduced on: OnePlus 9 Pro Android 12
Setting locale via AppCompatDelegate.setApplicationLocales doesnt work with application context on Android 12. In Android 13 the following snippet is using the in app language for both rows but on Android 12 first row is printed in phone locale and second one in app locale.
Log.d(TAG, applicationContext.getString(R.string.settings_change_button)) // Application context
Log.d(TAG, getString(R.string.settings_change_button)) // Activity context