是否有可能在使用Android资源的同时以编程方式改变应用程序的语言?

如果不是,是否可以用特定的语言请求资源?

我想让用户改变应用程序的语言从应用程序。


当前回答

这个功能是由谷歌为Android 13正式推出的(也有向后支持)。Android现在允许你为每个应用程序选择语言。

官方文件在这里- https://developer.android.com/guide/topics/resources/app-languages

要设置用户的首选语言,你会要求用户在语言选择器中选择一个地区,然后在系统中设置该值:

// 1. Inside an activity, in-app language picker gets an input locale "xx-YY"
// 2. App calls the API to set its locale
mContext.getSystemService(LocaleManager.class
    ).setApplicationLocales(newLocaleList(Locale.forLanguageTag("xx-YY")));
// 3. The system updates the locale and restarts the app, including any configuration updates
// 4. The app is now displayed in "xx-YY" language

要在语言选择器中显示用户当前的首选语言,你的应用程序可以从系统中获取返回的值:


// 1. App calls the API to get the preferred locale
LocaleList currentAppLocales =
    mContext.getSystemService(LocaleManager.class).getApplicationLocales();
// 2. App uses the returned LocaleList to display languages to the user

其他回答

创建一个类Extends Application并创建一个静态方法。 然后你可以在setContentView()之前的所有活动中调用这个方法。

public class MyApp extends Application {

@Override
public void onCreate() {
    super.onCreate();
}

public static void setLocaleFa (Context context){
    Locale locale = new Locale("fa"); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    context.getApplicationContext().getResources().updateConfiguration(config, null);
}

public static void setLocaleEn (Context context){
    Locale locale = new Locale("en_US"); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    context.getApplicationContext().getResources().updateConfiguration(config, null);
}

}

在活动中的使用:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyApp.setLocaleFa(MainActivity.this);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
}

这段代码真的可以工作:

fa = 波斯语,en = 英语

注意:语言代码不能有“-”,必须是2个小写字母

在languageToLoad变量中输入您的语言代码:

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;

public class Main extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String languageToLoad  = "fa"; // your language
    Locale locale = new Locale(languageToLoad); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config, 
      getBaseContext().getResources().getDisplayMetrics());
    this.setContentView(R.layout.main);
  }
}

2021年6月更新(Kotlin):

class Main : Activity() {
    // Called when the activity is first created.
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        val config = resources.configuration
        val lang = "fa" // your language code
        val locale = Locale(lang)
        Locale.setDefault(locale)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
            config.setLocale(locale)
        else
            config.locale = locale

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
            createConfigurationContext(config)
        resources.updateConfiguration(config, resources.displayMetrics)

        this.setContentView(R.layout.main)
    }
}

唯一完全适合我的解决方案是结合Alex Volovoy的代码和应用程序重启机制:

void restartApplication() {
    Intent i = new Intent(MainTabActivity.context, MagicAppRestart.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    MainTabActivity.context.startActivity(i);
}


/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        finish();
    }

    protected void onResume() {
        super.onResume();
        startActivityForResult(new Intent(this, MainTabActivity.class), 0);         
    }
}

Mayuri的答案是正确的,但这只适用于Api 33或更高的版本。以下是逐步向后兼容的解决方案:

步骤1:在res/xml文件夹下创建locales_config.xml。

//res/xml/locales_config.xml
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Add your required languages -->
    <locale android:name="hi" />
    <locale android:name="en" />
</locale-config>

步骤2:在Application的Manifest中添加localeConfig

<manifest>
<application
    android:localeConfig="@xml/locales_config">
</application>

步骤3:在Manifest中应用此服务

<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
  android:name="autoStoreLocales"
  android:value="true" />
</service>

步骤4:在应用程序的模块级构建中使用resConfigs属性指定相同的语言。gradle文件:

  android {
  defaultConfig {
      ...
      resConfigs "hi","en"
  }
  }

(要求appCompat版本1.6.0或更高)

implementation 'androidx.appcompat:appcompat:1.6.0'

第5步:现在你可以使用下面的代码来更改应用程序语言(在android 9,10,12和13上测试)

  LocaleListCompat appLocale = LocaleListCompat.forLanguageTags("hi"); //Give user selected language code 
  AppCompatDelegate.setApplicationLocales(appLocale);

在设置内容之前,应该在每个活动中设置区域配置- this.setContentView(r.b ayout.main);