Change the way we handle the locale change

This commit is contained in:
Nicolas Pomepuy
2019-08-09 12:21:08 +02:00
committed by Geoffrey Métais
parent 123e7cc1cc
commit 58fea994e1
13 changed files with 147 additions and 35 deletions

View File

@@ -22,19 +22,14 @@ package org.videolan.vlc
import android.app.PendingIntent
import android.app.Service
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.*
import android.os.*
import android.text.format.DateFormat
import androidx.core.app.NotificationCompat
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.vlc.gui.DebugLogActivity
import org.videolan.vlc.gui.helpers.NotificationHelper
import org.videolan.vlc.util.AndroidDevices
import org.videolan.vlc.util.Logcat
import org.videolan.vlc.util.Util
import org.videolan.vlc.util.*
import java.io.*
import java.util.*
@@ -46,6 +41,14 @@ class DebugLogService : Service(), Logcat.Callback, Runnable {
private val callbacks = RemoteCallbackList<IDebugLogServiceCallback>()
private val binder = DebugLogServiceStub(this)
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.getContextWithLocale())
}
override fun getApplicationContext(): Context {
return getContextWithLocale()
}
override fun onBind(intent: Intent): IBinder? {
return binder
}

View File

@@ -91,6 +91,14 @@ class MediaParsingService : Service(), DevicesDiscoveryCb, CoroutineScope, Lifec
}
}
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.getContextWithLocale())
}
override fun getApplicationContext(): Context {
return getContextWithLocale()
}
@SuppressLint("WakelockTimeout")
override fun onCreate() {
dispatcher.onServicePreSuperOnCreate()

View File

@@ -443,6 +443,14 @@ class PlaybackService : MediaBrowserServiceCompat(), CoroutineScope, LifecycleOw
get() = this@PlaybackService
}
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.getContextWithLocale())
}
override fun getApplicationContext(): Context {
return getContextWithLocale()
}
override fun onCreate() {
dispatcher.onServicePreSuperOnCreate()
super.onCreate()

View File

@@ -16,6 +16,7 @@ import org.videolan.libvlc.MediaPlayer
import org.videolan.vlc.media.MediaPlayerEventListener
import org.videolan.vlc.media.PlayerController
import org.videolan.vlc.util.VLCInstance
import org.videolan.vlc.util.getContextWithLocale
import org.videolan.vlc.util.getFromMl
import org.videolan.vlc.util.random
import java.io.IOException
@@ -32,6 +33,14 @@ class PreviewVideoInputService : TvInputService(), CoroutineScope {
return PreviewSession(this)
}
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.getContextWithLocale())
}
override fun getApplicationContext(): Context {
return getContextWithLocale()
}
private inner class PreviewSession(context: Context
) : TvInputService.Session(context), MediaPlayerEventListener {

View File

@@ -31,7 +31,10 @@ import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
import org.videolan.vlc.gui.helpers.BitmapUtil
@@ -47,6 +50,14 @@ class RecommendationsService : IntentService("RecommendationService"), Coroutine
private lateinit var mNotificationManager: NotificationManager
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.getContextWithLocale())
}
override fun getApplicationContext(): Context {
return getContextWithLocale()
}
override fun onCreate() {
super.onCreate()
mNotificationManager = getAppSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

View File

@@ -23,6 +23,7 @@
package org.videolan.vlc
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
@@ -38,7 +39,6 @@ import org.videolan.medialibrary.MLServiceLocator
import org.videolan.vlc.gui.BetaWelcomeActivity
import org.videolan.vlc.gui.MainActivity
import org.videolan.vlc.gui.SearchActivity
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.gui.onboarding.ONBOARDING_DONE_KEY
import org.videolan.vlc.gui.onboarding.startOnboarding
import org.videolan.vlc.gui.tv.MainTvActivity
@@ -75,9 +75,16 @@ class StartActivity : FragmentActivity() {
return 0
}
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.getContextWithLocale())
}
override fun getApplicationContext(): Context {
return getContextWithLocale()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (AndroidUtil.isNougatOrLater) UiTools.setLocale(this)
try {
if (!Settings.showTvUi && BuildConfig.BETA && !Settings.getInstance(this).getBoolean(BETA_WELCOME, false)) {

View File

@@ -24,6 +24,7 @@ import android.annotation.TargetApi
import android.app.Application
import android.content.ComponentName
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Configuration
@@ -46,11 +47,7 @@ import org.videolan.vlc.gui.dialogs.VlcProgressDialog
import org.videolan.vlc.gui.helpers.AudioUtil
import org.videolan.vlc.gui.helpers.BitmapCache
import org.videolan.vlc.gui.helpers.NotificationHelper
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.util.Settings
import org.videolan.vlc.util.Util
import org.videolan.vlc.util.VLCInstance
import org.videolan.vlc.util.runIO
import org.videolan.vlc.util.*
import java.lang.ref.WeakReference
import java.lang.reflect.InvocationTargetException
@@ -102,6 +99,9 @@ class VLCApplication : MultiDexApplication() {
//Initiate Kotlinx Dispatchers in a thread to prevent ANR
Thread(Runnable {
locale = Settings.getInstance(instance).getString("set_locale", "")
locale.takeIf { !it.isNullOrEmpty() }?.let {
instance = ContextWrapper(this).wrap(locale!!)
}
runIO(Runnable {
if (AndroidUtil.isOOrLater)
@@ -119,7 +119,9 @@ class VLCApplication : MultiDexApplication() {
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
UiTools.setLocale(appContext)
locale.takeIf { !it.isNullOrEmpty() }?.let {
instance = ContextWrapper(this).wrap(locale!!)
}
}
/**
@@ -147,8 +149,10 @@ class VLCApplication : MultiDexApplication() {
private const val TAG = "VLC/VLCApplication"
const val ACTION_MEDIALIBRARY_READY = "VLC/VLCApplication"
@SuppressLint("StaticFieldLeak")
@Volatile
private lateinit var instance: Application
private lateinit var instance: Context
private val dataMap = SimpleArrayMap<String, WeakReference<Any>>()

View File

@@ -31,7 +31,6 @@ import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import kotlinx.coroutines.*
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.tools.coroutineScope
import org.videolan.vlc.BuildConfig
import org.videolan.vlc.R
@@ -56,7 +55,6 @@ class AboutFragment : Fragment() {
(activity as? AppCompatActivity)?.supportActionBar?.title = "VLC ${BuildConfig.VERSION_NAME}"
//Fix android 7 Locale problem with webView
//https://stackoverflow.com/questions/40398528/android-webview-locale-changes-abruptly-on-android-n
if (AndroidUtil.isNougatOrLater) UiTools.setLocale(requireActivity())
val aboutMain = view.findViewById<ScrollView>(R.id.about_main)
val webView = view.findViewById<WebView>(R.id.webview)

View File

@@ -47,7 +47,6 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior.*
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout
import kotlinx.coroutines.*
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.tools.setVisibility
import org.videolan.vlc.*
@@ -104,8 +103,6 @@ open class AudioPlayerContainerActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//Init Medialibrary if KO
if (savedInstanceState != null) {
if (AndroidUtil.isNougatOrLater)
UiTools.setLocale(this)
this.startMedialibrary(firstRun = false, upgrade = false, parse = true)
}

View File

@@ -1,5 +1,6 @@
package org.videolan.vlc.gui
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.view.KeyEvent
@@ -8,22 +9,29 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import org.videolan.tools.KeyHelper
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.gui.helpers.applyTheme
import org.videolan.vlc.util.Settings
import org.videolan.vlc.util.getContextWithLocale
open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope() {
lateinit var settings: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
UiTools.setLocale(this)
settings = Settings.getInstance(this)
/* Theme must be applied before super.onCreate */
applyTheme()
super.onCreate(savedInstanceState)
}
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.getContextWithLocale())
}
override fun getApplicationContext(): Context {
return getContextWithLocale()
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
KeyHelper.manageModifiers(event)
return super.onKeyDown(keyCode, event)

View File

@@ -480,16 +480,6 @@ object UiTools {
win.attributes = winParams
}
fun setLocale(context: Context) {
VLCApplication.locale.takeIf { !it.isNullOrEmpty() }?.let {
val locale = getLocaleFromString(it)
Locale.setDefault(locale)
val config = Configuration()
config.locale = locale
context.resources.updateConfiguration(config,
context.resources.displayMetrics)
}
}
fun restartDialog(context: Context) {
AlertDialog.Builder(context)

View File

@@ -24,6 +24,7 @@
package org.videolan.vlc.gui.tv.browser
import android.annotation.TargetApi
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
@@ -41,6 +42,7 @@ import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.gui.tv.SearchActivity
import org.videolan.vlc.gui.tv.registerTimeView
import org.videolan.vlc.util.Settings
import org.videolan.vlc.util.getContextWithLocale
private const val TAG = "VLC/BaseTvActivity"
@@ -54,9 +56,16 @@ abstract class BaseTvActivity : FragmentActivity(), CoroutineScope by MainScope(
@Volatile
private var currentlyVisible = false
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase?.getContextWithLocale())
}
override fun getApplicationContext(): Context {
return getContextWithLocale()
}
override fun onCreate(savedInstanceState: Bundle?) {
//Init Medialibrary if KO
UiTools.setLocale(this)
if (savedInstanceState != null) startMedialibrary(firstRun = false, upgrade = false, parse = true)
super.onCreate(savedInstanceState)
mediaLibrary = AbstractMedialibrary.getInstance()

View File

@@ -0,0 +1,60 @@
package org.videolan.vlc.util
import android.annotation.TargetApi
import android.content.Context
import android.content.ContextWrapper
import android.os.Build
import org.videolan.vlc.VLCApplication
import java.util.*
@Suppress("DEPRECATION")
fun ContextWrapper.wrap(language: String): ContextWrapper {
val config = baseContext.resources.configuration
val sysLocale: Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
this.getSystemLocale()
} else {
this.getSystemLocaleLegacy()
}
if (language.isNotEmpty() && sysLocale.language != language) {
val locale = Locale(language)
Locale.setDefault(locale)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
this.setSystemLocale(locale)
} else {
this.setSystemLocaleLegacy(locale)
}
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
val context = baseContext.createConfigurationContext(config)
ContextWrapper(context)
} else {
baseContext.resources.updateConfiguration(config, baseContext.resources.displayMetrics)
ContextWrapper(baseContext)
}
}
@Suppress("DEPRECATION")
fun ContextWrapper.getSystemLocaleLegacy(): Locale = baseContext.resources.configuration.locale
@TargetApi(Build.VERSION_CODES.N)
fun ContextWrapper.getSystemLocale(): Locale = baseContext.resources.configuration.locales[0]
@Suppress("DEPRECATION")
fun ContextWrapper.setSystemLocaleLegacy(locale: Locale) {
baseContext.resources.configuration.locale = locale
}
@TargetApi(Build.VERSION_CODES.N)
fun ContextWrapper.setSystemLocale(locale: Locale) {
baseContext.resources.configuration.setLocale(locale)
}
fun Context.getContextWithLocale(): Context {
VLCApplication.locale.takeIf { !it.isNullOrEmpty() }?.let {
return ContextWrapper(this).wrap(it)
}
return this
}