2013-07-11 3 views
0

В Android-приложении мне нужно выбрать ресурсы из папки ресурсов, отличной от выбранной в данный момент (язык интерфейса - это то, что выбирает система, но пользователь может выбрать другой язык для TTS). Из-за того, как приложение структурировано, ресурсы переключения не являются опцией; Мне нужно как по умолчанию, так и альтернативный набор одновременно. Я был в состоянии использовать этот код, чтобы, например, выбрать испанские строки, когда пользовательский интерфейс был на английском языке:Как выбрать строку из папки ресурсов Android, отличной от текущей?

class SpanishStrings() 
{ 
    private Resources mResources; 

    public Foo(Context context) 
    { 
     final Resources oldResources = context.getResources(); 
     Configuration oldConfiguration = oldResources.getConfiguration(); 
     DisplayMetrics metrics = oldResources.getDisplayMetrics(); 
     Configuration configuration = new Configuration(oldConfiguration); 
     configuration.locale = new Locale("es", "es"); 
     mResources = new Resources(oldResources.getAssets(), metrics, configuration); 
    } 

    String getString(int id) 
    { 
     return mResources.getString(id); 
    } 
} 

Но это также устанавливается весь пользовательский интерфейс на Испанский! Может ли Android иметь только один активный ресурс за раз?

Это работает на Android 2.3.4, если это имеет значение.

ответ

0

Попробуйте изменить свой код, как это (взятый из https://stackoverflow.com/a/10879185/446963)

cMK = getResources().getStringArray(R.array.cities); 
Configuration confTmp =new Configuration(getResources().getConfiguration()); 
confTmp.locale = new Locale("en"); 
DisplayMetrics metrics = new DisplayMetrics(); 
getWindowManager().getDefaultDisplay().getMetrics(metrics); 
Resources resources = new Resources(getAssets(), metrics, confTmp); 
/* get localized string */ 
cENG = getResources().getStringArray(R.array.cities); 

В своем коде вы метрика и средство от первоначальных ресурсов к новым ресурсам. Поэтому я думаю, что любые изменения происходят с этими объектами в новых ресурсах и отфильтровываются обратно к исходным ресурсам.

Используя код выше, новые объекты создаются для всех необходимых параметров ресурсов. Просто догадайтесь, но посмотрите, работает ли это ...

+0

Приведенный выше код использует исходные активы() тоже, и мой код выше уже создает новую конфигурацию. Единственное отличие - это показатели, но я попробую. –

+0

Извините, не работает, но теперь я думаю, что знаю почему! Создание новых ресурсов обновляет активы, а AssetManager не предоставляет способ дублирования себя, что я вижу. –

2

Я нашел один способ заставить его работать. Учитывая класс в вопросе, удалите конструктор и изменить GetString() следующим образом:

String getString(int id) 
    { 
     final Resources oldResources = mContext.getResources(); 
     final Configuration oldConfiguration = oldResources.getConfiguration(); 
     final DisplayMetrics metrics = oldResources.getDisplayMetrics(); 
     final Configuration configuration = new Configuration(oldConfiguration); 
     configuration.locale = new Locale("es", "es"); 
     Resources resources = new Resources(oldResources.getAssets(), metrics, configuration); 
     final String result = resources.getString(id); 
     oldResources.updateConfiguration(oldConfiguration, metrics); 
     return result; 
    } 

Это updateConfiguration, что очень важно. Я просмотрел код для android.content.res.Resources, и выясняется, что конструктор Resource() вызывает updateConfiguration(), и что updateConfiguration() вызывает mAssets.setConfiguration(). Это означает, что любые изменения в конфигурации применяются ко всем пользователям одного и того же экземпляра AssetManager.

Я не выглядел глубже этого, и я знаю, что вышеупомянутый ответ можно было бы оптимизировать, сохранив два набора ресурсов и только вызывая updateConfiguration() вместо создания целого нового объекта Resources до и после извлечения строки, поэтому, если кто-нибудь знает, как создать совершенно новый экземпляр AssetManager(), то, пожалуйста, напишите лучший ответ, чем это!

EDIT: В моем текущем коде я сделал его менее болезненным для использования на подклассы ресурсы, например, так:

final oldResources = context.getResources(); 
final Configuration configuration = new Configuration(mDefaultResources.getConfiguration()); 
configuration.locale = new Locale("es", "es"); 
mResources = new Resources(mDefaultResources.getAssets(), mDefaultResources.getDisplayMetrics(), configuration) 
    { 
     @Override 
     public String getString(int id) throws NotFoundException 
     { 
      updateConfiguration(getConfiguration(), getDisplayMetrics()); 
      String result = super.getString(id); 
      oldResources.updateConfiguration(oldResources.getConfiguration(), oldResources.getDisplayMetrics()); 
      return result; 
     } 
    };