diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 63a17e0788..cfcf16915e 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1,6 +1,52 @@
+
+ - @string/preferences__default
+ - English
+ - Arabic العربية
+ - Burmese မြန်မာစာ
+ - Chinese 中国的
+ - Deutsch
+ - Español
+ - Français
+ - Italiano
+ - Japanese 日本人
+ - Magyar
+ - Nederlands
+ - Norsk
+ - Português
+ - Português (Brasil)
+ - Russian Pусский
+ - Slovenščina
+ - Slovenský
+ - Svenska
+ - Tibetan བོད་སྐད།
+
+
+
+ - zz
+ - en
+ - ar
+ - my
+ - zh_CN
+ - de
+ - es
+ - fr
+ - it
+ - ja
+ - he
+ - nl
+ - no
+ - pt
+ - pt_BR
+ - ru
+ - sl
+ - sk
+ - sv
+ - bo
+
+
- @string/preferences__minutes
- @string/preferences__hours
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7424a39ad2..fc814a5a69 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -445,6 +445,7 @@
Dark Theme
Appearance
Theme
+ Default
@@ -511,6 +512,7 @@
Verified
+ Language
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index c03094108c..b24af3ef9b 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -78,6 +78,12 @@
android:entryValues="@array/pref_theme_values"
android:defaultValue="light">
+
+
diff --git a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java
index fa3c8d3dd2..1d1757d9b0 100644
--- a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java
+++ b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java
@@ -25,27 +25,22 @@ import android.net.Uri;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
-import android.preference.PreferenceScreen;
import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
import android.provider.ContactsContract;
import android.util.Log;
import android.widget.Toast;
+import com.actionbarsherlock.view.MenuItem;
import org.thoughtcrime.securesms.contacts.ContactAccessor;
import org.thoughtcrime.securesms.contacts.ContactIdentityManager;
-import org.thoughtcrime.securesms.crypto.IdentityKey;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
-import org.thoughtcrime.securesms.util.Dialogs;
+import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.thoughtcrime.securesms.util.Trimmer;
-import org.thoughtcrime.securesms.util.Util;
-
-import com.actionbarsherlock.view.MenuItem;
-
-import java.util.List;
/**
* The Activity for application preference display and management.
@@ -72,6 +67,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
public static final String PASSPHRASE_TIMEOUT_PREF = "pref_timeout_passphrase";
public static final String AUTO_KEY_EXCHANGE_PREF = "pref_auto_complete_key_exchange";
public static final String THEME_PREF = "pref_theme";
+ public static final String LANGUAGE_PREF = "pref_language";
public static final String ENTER_SENDS_PREF = "pref_enter_sends";
public static final String ENTER_PRESENT_PREF = "pref_enter_key";
@@ -98,11 +94,13 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
public static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
public static final String GCM_PASSWORD_PREF = "pref_gcm_password";
- private final DynamicTheme dynamicTheme = new DynamicTheme();
+ private final DynamicTheme dynamicTheme = new DynamicTheme();
+ private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
protected void onCreate(Bundle icicle) {
dynamicTheme.onCreate(this);
+ dynamicLanguage.onCreate(this);
super.onCreate(icicle);
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@@ -134,6 +132,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
public void onResume() {
super.onResume();
dynamicTheme.onResume(this);
+ dynamicLanguage.onResume(this);
}
@Override
@@ -233,6 +232,8 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(THEME_PREF)) {
dynamicTheme.onResume(this);
+ } else if (key.equals(LANGUAGE_PREF)) {
+ dynamicLanguage.onResume(this);
}
}
diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java
index 318b7c4500..4b8648a939 100644
--- a/src/org/thoughtcrime/securesms/ConversationActivity.java
+++ b/src/org/thoughtcrime/securesms/ConversationActivity.java
@@ -80,6 +80,7 @@ import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.CharacterCalculator;
+import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.EncryptedCharacterCalculator;
import org.thoughtcrime.securesms.util.InvalidMessageException;
@@ -138,10 +139,12 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
private CharacterCalculator characterCalculator = new CharacterCalculator();
private DynamicTheme dynamicTheme = new DynamicTheme();
+ private DynamicLanguage dynamicLanguage = new DynamicLanguage();
@Override
protected void onCreate(Bundle state) {
dynamicTheme.onCreate(this);
+ dynamicLanguage.onCreate(this);
super.onCreate(state);
setContentView(R.layout.conversation_activity);
@@ -165,6 +168,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
protected void onResume() {
super.onResume();
dynamicTheme.onResume(this);
+ dynamicLanguage.onResume(this);
initializeSecurity();
initializeTitleBar();
diff --git a/src/org/thoughtcrime/securesms/ConversationListActivity.java b/src/org/thoughtcrime/securesms/ConversationListActivity.java
index 7cec2977cc..7f17cbe2a2 100644
--- a/src/org/thoughtcrime/securesms/ConversationListActivity.java
+++ b/src/org/thoughtcrime/securesms/ConversationListActivity.java
@@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.service.SendReceiveService;
+import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
@@ -39,7 +40,8 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
implements ConversationListFragment.ConversationSelectedListener,
ListView.OnItemClickListener
{
- private final DynamicTheme dynamicTheme = new DynamicTheme();
+ private final DynamicTheme dynamicTheme = new DynamicTheme ();
+ private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
private ConversationListFragment fragment;
private MasterSecret masterSecret;
@@ -49,6 +51,7 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
@Override
public void onCreate(Bundle icicle) {
dynamicTheme.onCreate(this);
+ dynamicLanguage.onCreate(this);
super.onCreate(icicle);
setContentView(R.layout.conversation_list_activity);
@@ -64,6 +67,7 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
public void onResume() {
super.onResume();
dynamicTheme.onResume(this);
+ dynamicLanguage.onResume(this);
}
@Override
diff --git a/src/org/thoughtcrime/securesms/util/DynamicLanguage.java b/src/org/thoughtcrime/securesms/util/DynamicLanguage.java
new file mode 100644
index 0000000000..6c70f829b4
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/util/DynamicLanguage.java
@@ -0,0 +1,70 @@
+package org.thoughtcrime.securesms.util;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Build;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
+
+import java.util.Locale;
+
+public class DynamicLanguage {
+
+ private static final String DEFAULT = "zz";
+
+ private Locale currentLocale;
+
+ public void onCreate(Activity activity) {
+ currentLocale = getSelectedLocale(activity);
+ setActivityLocale(activity, currentLocale);
+ }
+
+ public void onResume(Activity activity) {
+ if (!currentLocale.getLanguage().equalsIgnoreCase(getSelectedLocale(activity).getLanguage())) {
+ Intent intent = activity.getIntent();
+ intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+
+ activity.startActivity(intent);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
+ OverridePendingTransition.invoke(activity);
+ }
+
+ activity.finish();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
+ OverridePendingTransition.invoke(activity);
+ }
+ }
+ }
+
+ private static void setActivityLocale(Activity activity, Locale selectedLocale) {
+ Configuration configuration = activity.getResources().getConfiguration();
+
+ if (!configuration.locale.getLanguage().equalsIgnoreCase(selectedLocale.getLanguage())) {
+ configuration.locale = selectedLocale;
+ activity.getResources().updateConfiguration(configuration,
+ activity.getResources().getDisplayMetrics());
+ }
+ }
+
+ private static Locale getActivityLocale(Activity activity) {
+ return activity.getResources().getConfiguration().locale;
+ }
+
+ private static Locale getSelectedLocale(Activity activity) {
+ String language = PreferenceManager.getDefaultSharedPreferences(activity)
+ .getString(ApplicationPreferencesActivity.LANGUAGE_PREF, DEFAULT);
+
+ if (language.equals(DEFAULT)) return Locale.getDefault();
+ else return new Locale(language);
+ }
+
+ private static final class OverridePendingTransition {
+ static void invoke(Activity activity) {
+ activity.overridePendingTransition(0, 0);
+ }
+ }
+
+}