diff --git a/android/sdk/src/main/cpp/app/organicmaps/sdk/platform/Language.cpp b/android/sdk/src/main/cpp/app/organicmaps/sdk/platform/Language.cpp index 38035bddc..bd0597721 100644 --- a/android/sdk/src/main/cpp/app/organicmaps/sdk/platform/Language.cpp +++ b/android/sdk/src/main/cpp/app/organicmaps/sdk/platform/Language.cpp @@ -9,8 +9,7 @@ #include -/// This function is called from native c++ code -std::string GetAndroidSystemLanguage() +std::vector GetAndroidSystemLanguages() { static char const * DEFAULT_LANG = "en"; @@ -18,20 +17,31 @@ std::string GetAndroidSystemLanguage() if (!env) { LOG(LWARNING, ("Can't get JNIEnv")); - return DEFAULT_LANG; + return {DEFAULT_LANG}; } static jclass const languageClass = jni::GetGlobalClassRef(env, "app/organicmaps/sdk/util/Language"); - static jmethodID const getDefaultLocaleId = - jni::GetStaticMethodID(env, languageClass, "getDefaultLocale", "()Ljava/lang/String;"); - jni::TScopedLocalRef localeRef(env, env->CallStaticObjectMethod(languageClass, getDefaultLocaleId)); + static jmethodID const getSystemLocalesId = + jni::GetStaticMethodID(env, languageClass, "getSystemLocales", "()[Ljava/lang/String;"); - std::string res = jni::ToNativeString(env, (jstring)localeRef.get()); - if (res.empty()) - res = DEFAULT_LANG; + jni::TScopedLocalRef resultArray(env, env->CallStaticObjectMethod(languageClass, getSystemLocalesId)); - return res; + jobjectArray array = static_cast(resultArray.get()); + size_t len = env->GetArrayLength(array); + + std::vector languages; + languages.reserve(len); + + for (size_t i = 0; i < len; ++i) + { + jni::TScopedLocalRef elem(env, env->GetObjectArrayElement(array, i)); + std::string lang = jni::ToNativeString(env, static_cast(elem.get())); + + languages.push_back(lang); + } + + return languages; } namespace platform diff --git a/android/sdk/src/main/java/app/organicmaps/sdk/util/Language.java b/android/sdk/src/main/java/app/organicmaps/sdk/util/Language.java index e814eb4d3..758ee6581 100644 --- a/android/sdk/src/main/java/app/organicmaps/sdk/util/Language.java +++ b/android/sdk/src/main/java/app/organicmaps/sdk/util/Language.java @@ -1,11 +1,16 @@ package app.organicmaps.sdk.util; import android.content.Context; +import android.content.res.Resources; +import android.os.Build; +import android.os.LocaleList; import android.text.TextUtils; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import androidx.annotation.Keep; import androidx.annotation.NonNull; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; public class Language @@ -33,6 +38,36 @@ public class Language return lang; } + @Keep + @SuppressWarnings("unused") + @NonNull + public static String[] getSystemLocales() + { + List result = new ArrayList<>(); + + // Check for Android version high enough to support Locale Preference list + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + { + // Gets user language preference list, on system level - app-specific changes are not applied + // (For that a Context object would be necessary) + LocaleList list = Resources.getSystem().getConfiguration().getLocales(); + for (int i = 0; i < list.size(); i++) + { + String lang = list.get(i).toString(); + if (lang.startsWith("in")) + lang = "id"; + if (lang.startsWith("iw")) + lang = "he"; + result.add(lang); + } + } + else + { + result.add(Locale.getDefault().toString()); + } + return result.toArray(new String[0]); + } + // After some testing on Galaxy S4, looks like this method doesn't work on all devices: // sometime it always returns the same value as getDefaultLocale() @NonNull diff --git a/libs/platform/preferred_languages.cpp b/libs/platform/preferred_languages.cpp index a2c28d73b..abf5be684 100644 --- a/libs/platform/preferred_languages.cpp +++ b/libs/platform/preferred_languages.cpp @@ -24,7 +24,7 @@ #include #elif defined(OMIM_OS_ANDROID) /// Body for this function is inside android/sdk/src/main/cpp sources -std::string GetAndroidSystemLanguage(); +std::vector GetAndroidSystemLanguages(); #else #error "Define language preferences for your platform" #endif @@ -514,7 +514,9 @@ struct SystemLanguages } #elif defined(OMIM_OS_ANDROID) - m_langs.push_back(GetAndroidSystemLanguage()); + std::vector system_langs = GetAndroidSystemLanguages(); + for (auto const & lang : system_langs) + m_langs.push_back(lang); #else #error "Define language preferences for your platform" #endif