CopyPastor

Detecting plagiarism made easy.

Score: 1; Reported for: Exact paragraph match Open both answers

Possible Plagiarism

Reposted on 2019-07-20
by Y.S

Original Post

Original - Posted on 2016-11-18
by Y.S



            
Present in both answers; Present only in the new answer; Present only in the old answer;

The complete solution to this problem consists of three steps:
**STEP 1**:
In the `onCreate()` of your `BaseActivity` (or all your `Activity`s), set the `Locale` as follows:
@Override protected void onCreate(Bundle savedInstanceState) {
Utils.setLocale(Utils.getSavedLocale()); requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState);
...... ......
}
where `getSavedLocale()` is the `Locale` corresponding to the current region.
And the method `Utils.setLocale(...)` is defined as follows:
public static void setLocale(Locale locale){ Context context = MyApplication.getInstance(); Resources resources = context.getResources(); Configuration configuration = resources.getConfiguration(); Locale.setDefault(locale); configuration.setLocale(locale); configuration.setLayoutDirection(locale);
// updateConfiguration(...) is deprecated in N if (Build.VERSION.SDK_INT >= 25) { context = context.getApplicationContext().createConfigurationContext(configuration); context = context.createConfigurationContext(configuration); }
context.getResources().updateConfiguration(configuration, resources.getDisplayMetrics()); }
This sets the correct `Locale` in every `Activity`. This is enough for apps supporting API level 25. For API level 26 & above, **STEP 2** and **STEP 3** are also required.
**STEP 2**:
Override the following method in your `BaseActivity`:
@Override protected void attachBaseContext(Context newBase) { newBase = Utils.getLanguageAwareContext(newBase); super.attachBaseContext(newBase); }
where the function `getLanguageAwareContext(...)` is defined as follows:
public static Context getLanguageAwareContext(Context context){ Configuration configuration = context.getResources().getConfiguration(); Locale locale = getIntendedLocale(); configuration.setLocale(locale); configuration.setLayoutDirection(locale); return context.createConfigurationContext(configuration); }
This, along with **STEP 1**, sets the correct `Locale` in every `Activity` of your app for API level 26 and above.
One more step, however, is required for setting the language direction correctly ...
**STEP 3**:
In the `onCreate()` of your `BaseActivity`, add the following code:
if (Build.VERSION.SDK_INT >= 26) { getWindow().getDecorView().setLayoutDirection(Utils.isRTL() ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); }
where the `isRTL()` function is defined as follows:
public static boolean isRTL(){ return TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL; }









[Ted Hopp's answer][ted] managed to solve the problem, but he didn't address the question of ***why*** this occurs.
The reason is the changes made to the [`WebView`](https://developer.android.com/reference/android/webkit/WebView.html) class and its support package in Android 7.0.
**Background:**
Android's `WebView` is built using [WebKit](https://webkit.org/). While it was originally a part of AOSP, from KitKat onwards a decision was made to spin off `WebView` into a separate component called [Android System WebView](https://play.google.com/store/apps/details?id=com.google.android.webview&hl=en). It is essentially an Android system app that comes pre-installed with Android devices. It is periodically updated, just like other system apps such as Google Play Services and the Play Store app. You can see it in your list of installed system apps:
[![Android System WebView][1Thumb]][1]


**Android 7.0 changes**:
Starting with Android N, the Chrome app will be used to render any/all `WebView`s in third-party Android apps. In phones that have Android N out-of-the-box, the Android WebView System app is not present at all. In devices that have received an OTA update to Android N, the Android System WebView is disabled:
[![WebView disabled][2Thumb]][2]
and
[![WebView disabled][3Thumb]][3]
Moreover, multi-locale support has been introduced, with devices having more than one default language:
[![enter image description here][4Thumb]][4]
This has an important consequence for apps that have multiple languages. If your app has `WebView`s, then those are rendered using the Chrome app. Because Chrome is an Android app *in itself*, running in its own sandboxed process, it will not be bound to the locale set by your app. Instead, Chrome will revert to the primary device locale. For example, say your app locale is set to `ar-AE`, while the primary locale of the device is `en-US`. In this case, the locale of the `Activity` containing a `WebView` will change from `ar-AE` to `en-US`, and strings and resources from the corresponding locale folders will be displayed. You may see a mish-mash of LTR and RTL strings/resources on those `Activity`s that have `WebView`s.
**The Solution:**
The complete solution to this problem consists of two steps:
**STEP 1:**
First, reset the default locale manually in every `Activity`, or at least every `Activity` that has a `WebView`.
public static void setLocale(Locale locale){ Context context = MyApplication.getInstance(); Resources resources = context.getResources(); Configuration configuration = resources.getConfiguration(); Locale.setDefault(locale); configuration.setLocale(locale);
if (Build.VERSION.SDK_INT >= 25) { context = context.getApplicationContext().createConfigurationContext(configuration); context = context.createConfigurationContext(configuration); }
context.getResources().updateConfiguration(configuration, resources.getDisplayMetrics()); }
Call the above method before calling `setContentView(...)` in the `onCreate()` method of all your Activities. The `locale` parameter should be the default `Locale` that you wish to set. For example, if you wish to set Arabic/UAE as the default locale, you should pass `new Locale("ar", "AE")`. Or if you wish to set the default locale (i.e. the `Locale` that is automatically set by the operating system), you should pass `Locale.US`.
**STEP 2:**
Additionally, you need to add the following line of code:
new WebView(this).destroy();
in the `onCreate()` of your `Application` class (if you have one), and wherever else the user may be changing the language. This will take care of all kinds of edge cases that may occur on app restart after changing the language (you may have noticed strings in other languages or with the opposite alignment after changing the language on `Activities` that have `WebView`s on Android 7.0++).
As an addendum, [Chrome custom tabs](https://developer.chrome.com/multidevice/android/customtabs) are now the preferred way of rendering in-app web pages.
**References:**
**1.** [**Android 7.0 - changes for `WebView`**](https://developer.android.com/about/versions/nougat/android-7.0.html#webview).
**2.** [**Understanding WebView and Android security patches**](http://www.androidcentral.com/android-webview-security).
**3.** [**WebView for Android**](https://developer.chrome.com/multidevice/webview/overview).
**4.** [**WebView: From "Powered by Chrome" to straight up Chrome**](http://arstechnica.co.uk/gadgets/2016/08/android-7-0-nougat-review/12/).
**5.** [**Nougat WebView**](http://opengapps.org/blog/post/2016/10/06/nougat-webview/).
**6.** [**Android 7.0 Nougat**](http://opengapps.org/blog/post/2016/09/02/android-7.0-nougat/).
**7.** [**Android N Mysteries, Part 1: Android System WebView is just "Chrome" Now?**](https://plus.google.com/+RonAmadeo/posts/T9E3CoWMroG).


[1]: https://i.stack.imgur.com/JxwuK.png [1thumb]: https://i.stack.imgur.com/JxwuKl.png [2]: https://i.stack.imgur.com/IZ2Nz.png [2thumb]: https://i.stack.imgur.com/IZ2Nzl.png [3]: https://i.stack.imgur.com/W6OyP.png [3thumb]: https://i.stack.imgur.com/W6OyPl.png [4]: https://i.stack.imgur.com/oLHdL.png [4thumb]: https://i.stack.imgur.com/oLHdLl.png [ted]: https://stackoverflow.com/a/40480347

        
Present in both answers; Present only in the new answer; Present only in the old answer;