added multi language download support

This commit is contained in:
X1nto 2020-08-02 20:16:55 +04:00
parent 43867162d8
commit 50e05c4660
8 changed files with 208 additions and 409 deletions

View File

@ -1,29 +1,30 @@
package com.vanced.manager.core.downloader
import android.app.DownloadManager
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.IBinder
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.preference.PreferenceManager
import com.downloader.OnDownloadListener
import com.downloader.OnStartOrResumeListener
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.core.installer.AppInstaller
import com.vanced.manager.ui.fragments.HomeFragment
import com.vanced.manager.utils.DownloadHelper.download
import com.vanced.manager.utils.InternetTools.baseUrl
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
import com.vanced.manager.utils.InternetTools.getObjectFromJson
import com.vanced.manager.utils.NotificationHelper
import com.vanced.manager.utils.NotificationHelper.cancelNotif
import com.vanced.manager.utils.NotificationHelper.createBasicNotif
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
class MicrogDownloadService: Service() {
private var downloadId: Long = 0
//private var downloadId: Long = 0
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
//registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
downloadMicrog()
stopSelf()
return START_NOT_STICKY
@ -33,49 +34,60 @@ class MicrogDownloadService: Service() {
val context = this
runBlocking {
launch {
//val prefs = getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
val prefs = getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
val url = getObjectFromJson(
"${PreferenceManager.getDefaultSharedPreferences(context)
.getString("install_url", baseUrl)}/microg.json", "url")
.getString("install_url", baseUrl)}/microg.json", "url"
)
//downloadId = download(url, "apk", "microg.apk", this@MicrogDownloadService)
val channel = 420
PRDownloader.download(url, getExternalFilesDir("apk")?.path, "microg.apk")
.build()
.setOnStartOrResumeListener {
OnStartOrResumeListener {
prefs?.edit()?.putBoolean("isMicrogDownloading", true)?.apply()
}
}
.setOnProgressListener { progress ->
val mProgress = progress.currentBytes * 100 / progress.totalBytes
NotificationHelper.displayDownloadNotif(
channel,
mProgress.toInt(),
getFileNameFromUrl(url),
this@MicrogDownloadService
)
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
prefs?.edit()?.putBoolean("isMicrogDownloading", false)?.apply()
cancelNotif(channel, this@MicrogDownloadService)
val intent = Intent(this@MicrogDownloadService, AppInstaller::class.java)
intent.putExtra("path", "${getExternalFilesDir("apk")}/microg.apk")
intent.putExtra("pkg", "com.mgoogle.android.gms")
//val mIntent = Intent(HomeFragment.MICROG_DOWNLOADED)
//mIntent.action = HomeFragment.MICROG_DOWNLOADED
//LocalBroadcastManager.getInstance(this@MicrogDownloadService).sendBroadcast(mIntent)
startService(intent)
}
override fun onError(error: com.downloader.Error?) {
prefs?.edit()?.putBoolean("isMicrogDownloading", false)?.apply()
createBasicNotif(
getString(R.string.error_downloading, "Microg"),
channel,
this@MicrogDownloadService
)
}
})
downloadId = download(url, "apk", "microg.apk", this@MicrogDownloadService)
}
}
/*
val channel = 420
PRDownloader.download(apkUrl, filesDir.path, "microg.apk")
.build()
.setOnStartOrResumeListener { OnStartOrResumeListener { prefs?.edit()?.putBoolean("isMicrogDownloading", true)?.apply() } }
.setOnProgressListener { progress ->
val mProgress = progress.currentBytes * 100 / progress.totalBytes
NotificationHelper.displayDownloadNotif(
channel,
mProgress.toInt(),
getFileNameFromUrl(apkUrl),
this
)
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
prefs?.edit()?.putBoolean("isMicrogDownloading", false)?.apply()
cancelNotif(channel, this@MicrogDownloadService)
val intent = Intent(this@MicrogDownloadService, AppInstaller::class.java)
intent.putExtra("path", "${filesDir.path}/microg.apk")
intent.putExtra("pkg", "com.mgoogle.android.gms")
val mIntent = Intent(HomeFragment.MICROG_DOWNLOADED)
mIntent.action = HomeFragment.MICROG_DOWNLOADED
LocalBroadcastManager.getInstance(this@MicrogDownloadService).sendBroadcast(mIntent)
startService(intent)
}
override fun onError(error: Error) {
prefs?.edit()?.putBoolean("isMicrogDownloading", false)?.apply()
createBasicNotif(getString(R.string.error_downloading, "Microg"), channel, this@MicrogDownloadService)
}
})
*/
}
/*
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) == downloadId) {
@ -88,11 +100,12 @@ class MicrogDownloadService: Service() {
}
}
}
*/
override fun onDestroy() {
super.onDestroy()
cancelNotif(420, this)
unregisterReceiver(receiver)
//unregisterReceiver(receiver)
}
override fun onBind(intent: Intent?): IBinder? {

View File

@ -1,33 +1,37 @@
package com.vanced.manager.core.downloader
import android.app.DownloadManager
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.IBinder
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.preference.PreferenceManager
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.OnStartOrResumeListener
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.core.installer.RootSplitInstallerService
import com.vanced.manager.core.installer.SplitInstaller
import com.vanced.manager.ui.fragments.HomeFragment
import com.vanced.manager.utils.DownloadHelper.download
import com.vanced.manager.utils.InternetTools.baseUrl
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
import com.vanced.manager.utils.InternetTools.getObjectFromJson
import com.vanced.manager.utils.NotificationHelper.cancelNotif
import com.vanced.manager.utils.NotificationHelper.createBasicNotif
import com.vanced.manager.utils.NotificationHelper.displayDownloadNotif
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
class VancedDownloadService: Service() {
private var downloadId: Long = 0
private var apkType: String = "arch"
//private var downloadId: Long = 0
//private var apkType: String = "arch"
private var count: Int = 0
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
//registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
downloadSplits()
stopSelf()
return START_NOT_STICKY
@ -40,12 +44,12 @@ class VancedDownloadService: Service() {
runBlocking {
launch {
val defPrefs = PreferenceManager.getDefaultSharedPreferences(context)
val baseUrl = defPrefs.getString("install_url", baseUrl)
val vancedVer = getObjectFromJson("$baseUrl/vanced.json", "version")
val insallUrl = defPrefs.getString("install_url", baseUrl)
val vancedVer = getObjectFromJson("$installUrl/vanced.json", "version")
val prefs = getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
val variant = PreferenceManager.getDefaultSharedPreferences(context).getString("vanced_variant", "nonroot")
val lang = prefs?.getString("lang", "en")
val variant = defPrefs.getString("vanced_variant", "nonroot")
val lang = prefs?.getString("lang", "en")?.split(", ")?.toTypedArray()
val theme = prefs?.getString("theme", "dark")
val arch =
when {
@ -55,54 +59,50 @@ class VancedDownloadService: Service() {
}
val url =
when (type) {
"arch" -> "$baseUrl/apks/v$vancedVer/$variant/Arch/split_config.$arch.apk"
"theme" -> "$baseUrl/apks/v$vancedVer/$variant/Theme/$theme.apk"
"lang" -> "$baseUrl/apks/v$vancedVer/$variant/Language/split_config.$lang.apk"
"enlang" -> "$baseUrl/apks/v$vancedVer/$variant/Language/split_config.en.apk"
"arch" -> "$installUrl/apks/v$vancedVer/$variant/Arch/split_config.$arch.apk"
"theme" -> "$installUrl/apks/v$vancedVer/$variant/Theme/$theme.apk"
"lang" -> "$installUrl/apks/v$vancedVer/$variant/Language/split_config.${lang?.get(count)}.apk"
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
}
apkType = type
downloadId = download(url, "apks", getFileNameFromUrl(url), this@VancedDownloadService)
}
}
/*
val channel = 69
PRDownloader
.download(url, cacheDir.path, getFileNameFromUrl(url))
.build()
.setOnStartOrResumeListener { OnStartOrResumeListener { prefs?.edit()?.putBoolean("isVancedDownloading", true)?.apply() } }
.setOnProgressListener { progress ->
val mProgress = progress.currentBytes * 100 / progress.totalBytes
displayDownloadNotif(channel, mProgress.toInt(), getFileNameFromUrl(url), this)
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
when (type) {
"arch" -> downloadSplits("theme")
"theme" -> downloadSplits("lang")
"lang" -> {
if (lang == "en") {
prepareInstall(variant!!)
cancelNotif(channel, this@VancedDownloadService)
} else {
downloadSplits("enlang")
//apkType = type
//downloadId = download(url, "apks", getFileNameFromUrl(url), this@VancedDownloadService)
val channel = 69
PRDownloader
.download(url, cacheDir.path, getFileNameFromUrl(url))
.build()
.setOnStartOrResumeListener { OnStartOrResumeListener { prefs?.edit()?.putBoolean("isVancedDownloading", true)?.apply() } }
.setOnProgressListener { progress ->
val mProgress = progress.currentBytes * 100 / progress.totalBytes
displayDownloadNotif(channel, mProgress.toInt(), getFileNameFromUrl(url), this@VancedDownloadService)
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
when (type) {
"arch" -> downloadSplits("theme")
"theme" -> downloadSplits("lang")
"lang" -> {
if (count < lang?.count()!!) {
count++
downloadSplits("lang")
} else {
prepareInstall(variant!!)
cancelNotif(channel, this@VancedDownloadService)
}
}
}
"enlang" -> {
prepareInstall(variant!!)
cancelNotif(channel, this@VancedDownloadService)
}
}
}
override fun onError(error: Error) {
createBasicNotif(getString(R.string.error_downloading, "Vanced"), channel, this@VancedDownloadService)
}
})
*/
override fun onError(error: Error?) {
createBasicNotif(getString(R.string.error_downloading, "Vanced"), channel, this@VancedDownloadService)
}
})
}
}
}
/*
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val prefs = context?.getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
@ -128,6 +128,7 @@ class VancedDownloadService: Service() {
}
}
}
*/
private fun prepareInstall(variant: String) {
val intent = Intent()
@ -142,7 +143,7 @@ class VancedDownloadService: Service() {
override fun onDestroy() {
super.onDestroy()
cancelNotif(69, this)
unregisterReceiver(receiver)
//unregisterReceiver(receiver)
}
override fun onBind(intent: Intent?): IBinder? {

View File

@ -2,14 +2,11 @@ package com.vanced.manager.core.fragments
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.Toast
import androidx.navigation.findNavController
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.button.MaterialButton
import com.topjohnwu.superuser.Shell
import com.vanced.manager.R
import com.vanced.manager.core.base.BaseFragment
@ -20,13 +17,6 @@ import com.vanced.manager.utils.PackageHelper.uninstallApk
open class Home : BaseFragment(), View.OnClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onResume() {
super.onResume()
val prefs = activity?.getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
@ -39,8 +29,6 @@ open class Home : BaseFragment(), View.OnClickListener {
override fun onClick(v: View?) {
val prefs = activity?.getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
val isVancedDownloading: Boolean? = prefs?.getBoolean("isVancedDownloading", false)
val isMicrogDownloading: Boolean? = prefs?.getBoolean("isMicrogDownloading", false)
val variant = getDefaultSharedPreferences(activity).getString("vanced_variant", "nonroot")
val vancedPkgName =
if (variant == "root") {
@ -51,32 +39,20 @@ open class Home : BaseFragment(), View.OnClickListener {
when (v?.id) {
R.id.vanced_installbtn -> {
if (!isVancedDownloading!!) {
try {
activity?.cacheDir?.deleteRecursively()
} catch (e: Exception) {
Log.d("VMCache", "Unable to delete cacheDir")
}
if (prefs.getBoolean("valuesModified", false)) {
activity?.startService(
Intent(
activity,
VancedDownloadService::class.java
)
if (prefs?.getBoolean("valuesModified", false)!!) {
activity?.startService(
Intent(
activity,
VancedDownloadService::class.java
)
} else {
view?.findNavController()?.navigate(R.id.toInstallThemeFragment)
}
)
} else {
Toast.makeText(activity, activity?.getString(R.string.installation_wait), Toast.LENGTH_SHORT).show()
view?.findNavController()?.navigate(R.id.toInstallThemeFragment)
}
}
R.id.microg_installbtn -> {
if (!isMicrogDownloading!!) {
activity?.startService(Intent(activity, MicrogDownloadService::class.java))
} else {
Toast.makeText(activity, activity?.getString(R.string.installation_wait), Toast.LENGTH_SHORT).show()
}
activity?.startService(Intent(activity, MicrogDownloadService::class.java))
}
R.id.microg_uninstallbtn -> activity?.let { uninstallApk("com.mgoogle.android.gms", it) }
R.id.vanced_uninstallbtn -> activity?.let { uninstallApk(vancedPkgName, it) }

View File

@ -1,37 +0,0 @@
package com.vanced.manager.core.fragments
import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.RadioButton
import android.widget.RadioGroup
import androidx.navigation.findNavController
import com.vanced.manager.R
import com.vanced.manager.core.base.BaseFragment
open class LanguageInstall : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val finishButton = view.findViewById<Button>(R.id.vanced_install_finish)
val langGroup = view.findViewById<RadioGroup>(R.id.lang_radiogroup)
val prefs = activity?.getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
val langPref = prefs?.getString("lang", "en")
val button = langGroup.findViewWithTag<RadioButton>(langPref)
button.isChecked = true
finishButton.setOnClickListener {
val selectedLangId = langGroup.checkedRadioButtonId
val selectedButton = view.findViewById<RadioButton>(selectedLangId)
prefs?.edit()?.putString("lang", selectedButton.tag.toString())?.apply()
prefs?.edit()?.putBoolean("isInstalling", true)?.apply()
prefs?.edit()?.putBoolean("valuesModified", true)?.apply()
view.findNavController().navigate(R.id.action_installTo_homeFragment)
}
}
}

View File

@ -1,34 +0,0 @@
package com.vanced.manager.core.fragments
import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.RadioButton
import android.widget.RadioGroup
import androidx.navigation.findNavController
import com.vanced.manager.R
import com.vanced.manager.core.base.BaseFragment
open class ThemeInstall : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val nextButton = view.findViewById<Button>(R.id.vanced_next_to_variant)
val themeGroup = view.findViewById<RadioGroup>(R.id.theme_radiogroup)
val prefs = activity?.getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
val themePref = prefs?.getString("theme", "dark")
val button = themeGroup.findViewWithTag<RadioButton>(themePref)
button.isChecked = true
nextButton.setOnClickListener {
val selectedThemeId = themeGroup.checkedRadioButtonId
val selectedButton = view.findViewById<RadioButton>(selectedThemeId)
prefs?.edit()?.putString("theme", selectedButton.tag.toString())?.apply()
view.findNavController().navigate(R.id.toInstallLanguageFragment)
}
}
}

View File

@ -4,10 +4,25 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.CheckBox
import android.widget.LinearLayout
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment
import androidx.navigation.findNavController
import androidx.preference.PreferenceManager
import com.beust.klaxon.JsonObject
import com.beust.klaxon.Parser
import com.github.kittinunf.fuel.coroutines.awaitString
import com.github.kittinunf.fuel.httpGet
import com.google.android.material.button.MaterialButton
import com.vanced.manager.R
import com.vanced.manager.core.fragments.LanguageInstall
import com.vanced.manager.utils.InternetTools.baseUrl
import kotlinx.coroutines.runBlocking
import java.util.*
class VancedLanguageSelectionFragment : LanguageInstall() {
class VancedLanguageSelectionFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@ -17,4 +32,47 @@ class VancedLanguageSelectionFragment : LanguageInstall() {
return inflater.inflate(R.layout.fragment_vanced_language_selection, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
runBlocking {
loadBoxes(view.findViewById(R.id.lang_button_ll))
}
view.findViewById<MaterialButton>(R.id.vanced_install_finish).setOnClickListener {
runBlocking {
val chosenLangs = mutableListOf("en")
for (lang in getLangs()!!) {
if (view.findViewWithTag<CheckBox>(lang).isChecked) {
chosenLangs.add(lang)
}
}
PreferenceManager.getDefaultSharedPreferences(activity).edit()?.putString("lang", chosenLangs.joinToString())?.apply()
view.findNavController().navigate(R.id.action_installTo_homeFragment)
}
}
}
private suspend fun getLangs(): Array<String>? {
val langObj = Parser.default().parse(
StringBuilder(
"https://${PreferenceManager.getDefaultSharedPreferences(activity).getString("update_url", baseUrl)}/vanced.json".httpGet().awaitString()
)
) as JsonObject
return langObj.array<String>("langs")?.toTypedArray()
}
private suspend fun loadBoxes(ll: LinearLayout) {
if (getLangs() != null) {
for (lang in getLangs()!!) {
val box: CheckBox = CheckBox(activity).apply {
tag = lang
text = Locale(lang).displayLanguage
textSize = 16F
typeface = activity?.let { ResourcesCompat.getFont(it, R.font.exo_bold) }
}
ll.addView(box, MATCH_PARENT, WRAP_CONTENT)
}
}
}
}

View File

@ -1,13 +1,18 @@
package com.vanced.manager.ui.fragments
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.RadioButton
import android.widget.RadioGroup
import androidx.fragment.app.Fragment
import androidx.navigation.findNavController
import com.vanced.manager.R
import com.vanced.manager.core.fragments.ThemeInstall
class VancedThemeSelectionFragment : ThemeInstall() {
class VancedThemeSelectionFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@ -17,4 +22,19 @@ class VancedThemeSelectionFragment : ThemeInstall() {
return inflater.inflate(R.layout.fragment_vanced_theme_selection, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val nextButton = view.findViewById<Button>(R.id.vanced_next_to_variant)
val themeGroup = view.findViewById<RadioGroup>(R.id.theme_radiogroup)
val prefs = activity?.getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
nextButton.setOnClickListener {
val selectedThemeId = themeGroup.checkedRadioButtonId
val selectedButton = view.findViewById<RadioButton>(selectedThemeId)
prefs?.edit()?.putString("theme", selectedButton.tag.toString())?.apply()
view.findNavController().navigate(R.id.toInstallLanguageFragment)
}
}
}

View File

@ -7,221 +7,23 @@
android:fillViewport="true"
tools:ignore="HardcodedText">
<RadioGroup
android:id="@+id/lang_radiogroup"
<LinearLayout
android:id="@+id/lang_button_ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:checkedButton="@id/en">
android:orientation="vertical">
<com.google.android.material.radiobutton.MaterialRadioButton
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/en"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="English (default)"
android:tag="en"
android:textSize="18sp" />
android:textSize="18sp"
android:checked="true"
android:clickable="false"/>
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Indonesian"
android:tag="in"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Català"
android:tag="ca"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Deutsch"
android:tag="de"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Español"
android:tag="es"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Français"
android:tag="fr"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Hrvatski"
android:tag="hr"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Italiano"
android:tag="it"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Magyar"
android:tag="hu"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Dutch"
android:tag="nl"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Polski"
android:tag="pl"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Português (Brasil)"
android:tag="pt"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Română"
android:tag="ro"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Suomi"
android:tag="fi"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Svenska"
android:tag="sv"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Tiếng Việt"
android:tag="vi"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Türkçe"
android:tag="tr"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Ελληνικά"
android:tag="hy"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Български"
android:tag="bg"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Русский"
android:tag="ru"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="Українська"
android:tag="uk"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="العربية"
android:tag="ar"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="ქართული"
android:tag="ka"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="日本語"
android:tag="ja"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="繁體中文"
android:tag="zh"
android:textSize="18sp" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/exo_semibold"
android:text="한국어"
android:tag="ko"
android:textSize="18sp" />
</RadioGroup>
</LinearLayout>
</androidx.core.widget.NestedScrollView>