Android 8.0 App内切替言語が有効でない問題記録


国内のほとんどの単純は中国語の簡体字版しか作られていないはずだが、一部のプロジェクトは国際化に向けなければならない.そのため、APP内の多言語切り替えが必要な機能のニーズに遭遇することがあります.どのように多言語の切り替えをして、ネット上の資料はまだ多くて、本文もどのようにこの機能をすることを記録するのではありませんて、詳しく説明しません.当社のプロジェクトのやり方を簡単に説明します.
1.初めてアプリをインストールし、携帯電話の言語設定を読み取る.この言語APP内に適合がある場合、APP言語もこの種類を使用します.そうしないと、デフォルトでは英語が使用されます.システムはこの値を覚え、その後、携帯電話の言語が変わっても、アプリは初めて開いたときに覚えた言語を使用します.2.ユーザーはAPP内の設定内でオプションの言語を切り替えることができ、後続のシステムはこの値を覚え、ユーザーが再びAPP内で言語を交換しない限り、毎回この言語を使用します.3.技術角度分析、他言語の交換をクリックした場合、言語設定値をローカルに保存し、放送通知言語の交換を送信する.最初はこのように処理され、各ActivityはBaseActivityから継承され、BaseActivityでブロードキャスト動的登録が行われています(ブロードキャストの静的登録と動的登録についてもくどくどしません).さらに、この言語の後に呼び出されてAPPの言語構成を変更する方法で、この方法はグローバルに変化してから広告を送信し、各Activityは動的に広告を登録し、言語交換のブロードキャストを傍受した後、recreateメソッドを呼び出すと、生存しているActivityごとに再起動して交換されます設定された言語.
次のコードクリップは、言語設定を更新したコードの一部です.
Resources resources = mContext.getApplicationContext().getResources();
DisplayMetrics dm = resources.getDisplayMetrics();
Configuration config = resources.getConfiguration();

config.locale = getSetLocale(); // getSetLocale           
resources.updateConfiguration(config, dm);

余談ですが、実は微信のようなアプリがあります.言語を変えるときはメインインタフェースに戻りますが、私がここで採用しているのは元のインタフェースに滞在してすべてのインタフェースをrecreateする方法も個人の好みと需要を見ています.現在設定されている元のインタフェースはフラッシュして言語を切り替えます.受け入れられない場合は微信アプリの方法に従ってください.それから言語の交換方法についてもいろいろな方法がありますが、一般的にはツール類などを書いたり、ラジオを使ってアプリ全体の言語切り替えを知らせるかどうかは自分で決めます.
一、8.0アンドロイドシステム放送では問題は何ですか.これまでこの方法を使っていたので問題はありませんでした.しかし、最近香港の同僚がアプリをテストしている間に、彼の携帯電話が言語を切り替えることができないことに気づき、私たちはOKしました.彼の携帯電話システムは8.0のシステムだと聞いた.8.0シミュレータを使用してテストした後もこの問題を発見し、デバッグして放送受信者が広告を受け取っていないことを発見し、不思議に思って、それからアンドロイド8.0システムの放送問題を検索して、それから8.0システムが放送に対していくつかの処理をしたことを知って、実は7.0で始まって、ただ8.0システムが徹底的に大きく変更して前の放送方法が通じないことを招きました.ネット上では2つの解決策が与えられており、動的ブロードキャスト登録や静的登録に対して指定されたブロードキャスト外のパケット名、受信者の全パスクラス名を追加するが、どこが問題なのか分からない.私はもともと動的登録だったのだが...私がそれぞれベースクラスを継承し、各ベースクラスが動的に登録したためか考えたことがある.しかし、私もこのような動的登録方式が望ましくないことを認識したので、いっそ静的登録を試み、放送を傍受することに成功した.
そこで私は各インタフェースの動的登録言語をラジオに変えて静的登録放送に変更しました.私たちの工事内にはActivityリストが記録されています.当初はアプリ全体をよりよく処理するために使用されていましたが、ここでは静的登録のラジオでラジオを受信した後、Activityリスト全体を呼び出して各クラスでrecreate方法を実行することができます.差は多くありませんが、しかし、より統一的で管理が容易になり、交換後も8.0システムでブロードキャストを受け取ることができます.
以前にブロードキャストを送信したコードは、簡単で、8.0以前のシステムで動作しても問題ありません.
Intent intent = new Intent();
intent.setAction("XXX");
mContext.sendBroaast(intent);

静的にブロードキャストを登録し、8.0システムのブロードキャスト問題を解決するコードは、そのパケット名とどのブロードキャスト受信者クラスにブロードキャストが送信されるかを指定します.
Intent intent = new Intent(mContext, XXXBroadcastReceiver.class);
intent.setPackage("com.XXX.app");
intent.setComponent(new ComponentName("com.XXX.app", "com.XXX.XXXBroadcastReceiver"));
intent.setAction("XXX");
mContext.sendBroadcast(intent);

放送形式で知らせるのでなければ、これらのものはあまり関係ありませんが、もしあなたのアプリにも放送が使われていて、まだ8.0をしていないなら、急いで8.0携帯電話のテストを取って、問題があれば急いで適切な処理をしましょう.
二、8.0アンドロイドシステムAPP内の言語変更放送は傍受でき、recreateメソッドも呼び出されたが、言語は確かに変わっていない.これはおかしいですね.急いでアンドロイド8.0システムの言語切替問題を検索し続けます.言語切替の変更もそんなに大きいですね.
1、まず、前の言語でコードを変更するには特別な処理が必要です.高バージョンシステムに対してsetLocaleのメソッドが呼び出されました.また、ここのContextでは、ApplicationContextを使用することを推奨します.しかし、ネット上には8.0言語の切り替え方法のコードがあります.ここのContextが現在のインタフェースのコンテキストを使用する必要があります.この方法は面倒で、Activityごとにこのように処理する必要がありますが、彼らの方法はContextがインタフェースのコンテキストを使用しなければ有効にならないので、この方法は望ましくありません.ここでApplicationContextを使用した後、各インタフェースに具体的に有効にする方法については、後述します.
Resources resources = mContext.getApplicationContext().getResources();
DisplayMetrics dm = resources.getDisplayMetrics();
Configuration config = resources.getConfiguration();

Locale locale = getSetLocale();// getSetLocale           
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    config.setLocale(locale);
} else {
    config.locale = locale;
}
resources.updateConfiguration(config, dm);

2、実は多言語切り替えをしたアプリでは、アプリケーションクラスのonCreateメソッドで、そのアプリの設定を読み取った言語を設定交換する方法が実行されますが、アプリケーションクラスにこのコードを追加する必要があります.
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    XXXX(); //            APP     
}

3、言語切替のコードは、高バージョンでupdateConfigurationメソッドが廃棄され、代替メソッドはcreateConfigurationContextである.この方法は、言語がContextにインプラントされ、各Contextがインプラントされる必要があるContextを返すことです.もちろん私たちはそんなに馬鹿ではありません.ベースクラスがあるので、BaseActivityに次のコードを追加しました.
@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(XXXUtils.attachBaseContext(base));
}

XXXUtilsコードのattachBaseContextメソッドを処理しました.
public Context attachBaseContext(Context context) {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 8.0    createConfigurationContext  
       return updateResources(context);
   } else {
       return context;
   }
}

@TargetApi(Build.VERSION_CODES.N)
private Context updateResources(Context context) {
    Resources resources = context.getResources();
    Locale locale = getSetLocale();// getSetLocale           

    Configuration configuration = resources.getConfiguration();
    configuration.setLocale(locale);
    configuration.setLocales(new LocaleList(locale));
    return context.createConfigurationContext(configuration);
}

これで、8.0シミュレータでテストして、正常に言語を交換することができます.この文章は自分の適当な簡単な記録として、まだ適当なアンドロイド開発者に適当なものを作る必要があることを注意した.以下に私の参考にした文章とGithubのDemoを提供して、必要なものがあれば見て、Demoの中には書くツール類などがあります.皆さんは私と同じように自分の状況に応じてコードを参考にして自分で処理することができます.間違いがあれば指摘したり交流したりして、疑問があれば伝言を残したりすることができます.
参考記事:https://yanlu.me/android-7-0-app-language-switch/参考Demo:https://github.com/captain-miao/MultiLanguagesSwitch
20190219更新appでシステムの言語設定を知る必要がある場合、いくつかの場所でシステム言語に基づいていくつかの処理を行うか、言語設定リストにシステムに従うオプションが必要である場合、実践的に実行可能な解決策は次のとおりです.
以前の設定言語コードは、すべて設定を保存する言語が携帯電話のローカルにあり、アプリケーション起動時に保存した言語設定を読み出して設定を行い、いったん手動で設定を変更すると、その後に取得する言語はすべて設定を取得した後になるので、起動手順アプリケーションの初期化において、システム言語の保存を取得してからappを他の言語を表示するように設定します.言語設定の変更は、システムに従うことができます.アプリケーションのonConfigurationChangedでは、アプリケーションの使用中にシステム言語設定の変更をリスニングすることで、リアルタイムで正しいシステム言語が保存されることを保証します.(微信のフォローアップシステムは、微信の使用中にシステム言語を変更した後、システム言語の設定に従って設定を読み取ることができる前のシステム言語は、このリスニングリセットをしていない可能性があります.もちろん、これらは小さな問題であり、一般のユーザーもこのように操作しません)テストによってシステム言語の変更が発見されました.アプリケーションはonCreateメソッドを再実行するわけではありませんが、onConfigurationChangedがトリガーされ、インタフェースも再onCreateされます.
onConfigurationChangedは、縦横画面切り替え時にもトリガーされ、もう1つの方法はブロードキャストを傍受し、システム言語変更時にブロードキャストACTION_をトリガーするLOCALE_CHANGEDは、テストされていませんが、onConfigurationChangedメソッドよりも適切であるはずです.