Android - Android 7.0以降でWebViewの言語が突然変更される。
質問
第一言語が英語、第二言語がアラビア語の多言語アプリを持っています。
に記載されているように ドキュメント ,
-
を追加しました。
android:supportsRtl="true"
をマニフェストに追加しました。 -
ですべての xml プロパティを変更しました。
left
とright
属性からstart
とend
をそれぞれ指定します。 -
にアラビア語の文字列を追加しました。
strings-ar
に追加しました (他のリソースについても同様です)。
上記の設定は正しく動作します。を変更した後
Locale
を
ar-AE
に変更すると、アラビア語のテキストとリソースがアクティビティに正しく表示されるようになりました。
しかし
Activity
に移動するたびにWebView
またはWebViewClient
である場合、ロケール、テキスト、レイアウト方向は は突然デバイスのデフォルトに戻ります。
さらにヒントがあります。
- この現象は だけ でNexus 6Pに Android 7.0 . Android 6.0.1 以下では、すべて正常に動作します。
-
ロケールの突然の移動が発生する
だけ
に移動すると
Activity
を持つWebView
とWebViewClient
(のどちらかで発生します(複数あります)。他のアクティビティでは発生しません。
Android 7.0 はマルチロケールをサポートしており、ユーザーが複数のデフォルトロケールを設定することができます。そのため、プライマリ ロケールを
Locale.UK
:
に移動すると
WebView
に移動すると、ロケールはar-AE
からen-GB
.
Android 7.0のAPIの変更点です。
で示したように API 変更点リスト にあるように、API24では以下のクラスにロケールに関連する新しいメソッドが追加されました。
Locale
:
Configuration
:
しかし、私はAPI 23でアプリを構築しており、これらの新しいメソッドを使用していません。 これらの新しいメソッドは使用していません。
さらに ...
-
この問題は、Nexus 6P エミュレータでも発生します。
-
デフォルトのロケールを取得するために、私は
Locale.getDefault()
. -
デフォルトのロケールを設定するために、以下のコードを使用しています。
public static void setLocale(Locale locale){ Locale.setDefault(locale); Configuration config = new Configuration(); config.setLocale(locale); Context context = MyApplication.getInstance(); context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics()); }
この問題に遭遇したことのある方はいらっしゃいますか?また、どのように解決すればよいのでしょうか?
リファレンスです。
1. Android 4.2でのネイティブRTLサポート .
2. 多言語対応 - 言語とロケール .
3. デフォルトのロケールに注意 .
どのように解決するのですか?
テッド・ホップ氏の回答 は、なんとか問題を解決してくれたのですが、次のような疑問には答えてくれませんでした。 なぜ が発生するのか。
の変更に起因するものです。
WebView
クラスとそのサポートパッケージが Android 7.0 で変更されたためです。
背景です。
アンドロイドの
WebView
を使って構築されています。
WebKit
. 元々は AOSP の一部でしたが、KitKat 以降は
WebView
という別のコンポーネントに分離することが決定されました。
Android システム WebView
. これは、基本的に Android デバイスにプレインストールされている Android システム アプリです。Google Play サービスや Play ストア アプリなど、他のシステム アプリと同様に定期的に更新されます。インストールされているシステム アプリのリストで確認できます。
Android 7.0 の変更点 :
Android N からは、Chrome アプリが、あらゆる/すべての
WebView
のレンダリングに使用されます。Android N を最初から搭載している電話機では、Android WebView システム アプリはまったく存在しません。Android NへのOTAアップデートを受けたデバイスでは、Android System WebViewは無効になります。
そして
さらに、マルチロケールサポートが導入され、複数のデフォルト言語を持つデバイスに対応しました。
これは、複数の言語を持つアプリにとって重要な結果をもたらします。もしアプリが
WebView
がある場合、これらは Chrome アプリを使用してレンダリングされます。ChromeはAndroidアプリであるため
それ自体
であり、独自のサンドボックス プロセスで実行されるため、アプリによって設定されたロケールに拘束されません。その代わり、Chrome は主要なデバイスのロケールに戻ります。たとえば、アプリのロケールが次のように設定されているとします。
ar-AE
に設定されており、デバイスのプライマリロケールが
en-US
. この場合、ロケールは
Activity
を含む
WebView
から
ar-AE
から
en-US
と入力すると、対応するロケールフォルダ内の文字列やリソースが表示されます。LTRとRTLの文字列やリソースが混在して表示されるかもしれません。
Activity
を持つ
WebView
s.
解決策
この問題の完全な解決策は2つのステップで構成されています。
ステップ1:
まず、デフォルトロケールを手動でリセットして、すべての
Activity
で、あるいは少なくともすべての
Activity
を持つものであれば
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());
}
上記のメソッドを呼び出す前に
setContentView(...)
の中で
onCreate()
メソッドに追加します。その
locale
パラメータはデフォルトの
Locale
を指定します。たとえば、アラビア語/UAE をデフォルトのロケールとして設定したい場合は、パラメータに
new Locale("ar", "AE")
. また、デフォルトのロケールを設定したい場合 (すなわち
Locale
が自動的に設定されるもの) を設定したい場合は、その前に
Locale.US
.
STEP2です。
さらに、以下のコードの行を追加する必要があります。
new WebView(this).destroy();
の中に
onCreate()
の
Application
クラス (もしあれば) の Activities
を持つ
WebView
がある場合)。
追記として Chrome カスタム タブ は現在、アプリ内の Web ページをレンダリングする好ましい方法です。
参考文献です。
1.
Android 7.0 - の変更点
WebView
.
2. WebViewとAndroidのセキュリティパッチを理解する .
3. Android用WebView .
4. WebView。"Powered by Chrome" からストレート アップ Chrome へ。 .
5. NougatのWebView .
6. Android 7.0 Nougat .
7. Android Nの謎、その1。Android System WebViewはただの"Chrome"になったのか? .
関連
-
[解決済み] Androidのgravityとlayout_gravityの違いは何ですか?
-
[解決済み] Androidで現在の時刻と日付を取得する方法
-
[解決済み] Androidのウェブビューでloadurlを呼び出すとブラウザが起動する
-
[解決済み] Nexus 4でUSBデバッグモードを見つける方法とオンにする方法
-
[解決済み] アンドロイドフラグメント onRestoreInstanceState
-
[解決済み] CardView layout_width="match_parent "が親のRecyclerViewの幅と一致しない。
-
[解決済み] ViewPagerのアイテムを強制的に再インスタンス化する方法 [重複].
-
[解決済み] これはどういうことですか?失敗 [INSTALL_FAILED_CONTAINER_ERROR]?
-
[解決済み] Android: ランドスケープモード用の代替レイアウト xml
-
[解決済み] Android APKファイルの中身を見るには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ArrayAdapter<myClass> の使用方法
-
[解決済み] Nexus 4でUSBデバッグモードを見つける方法とオンにする方法
-
[解決済み] AndroidでラジオボタンにOnClickListenerを設定するには?
-
[解決済み] XMLで矩形を描画できますか?
-
[解決済み] react nativeアプリのバージョン番号を更新する方法
-
[解決済み] Android APKファイルの中身を見るには?
-
[解決済み] Android: xml リソースからの整数値
-
[解決済み] LayoutParamsの高さを密度に依存しないピクセル数でプログラム的に設定する。
-
[解決済み] Android Studioでプロジェクトに含まれるすべてのハードコードされた文字列を見つけるには?
-
[解決済み] Androidで異なるロケールから文字列を取得する方法は?