ソースコード source code

下記アプリの主要なソースコードを公開しています。アプリ開発の参考になれば幸いです。

画像等が別途必要ですので下記情報のみでアプリが完成するものではありません。 アプリは少しずつ機能拡張していますのでストア公開されているアプリと内容が異なる場合があります。 コードはコピーして自由にお使いいただけます。ただし著作権は放棄しておりませんので全部の再掲載はご遠慮ください。部分的に再掲載したり、改変して再掲載するのは構いません。 自身のアプリ作成の参考として個人使用・商用問わず自由にお使いいただけます。 コード記述のお手本を示すものではありません。ミニアプリですので変数名などさほど気遣いしていない部分も有りますし間違いも有るかと思いますので参考程度にお考え下さい。 他の賢者の皆様が公開されているコードを参考にした箇所も含まれます。Androidアプリ開発の熟練者が書いたコードではありません。 エンジニア向け技術情報共有サービスではありませんので説明は省いています。ご了承ください。 GitHubなどへの公開は予定しておりません。

下記コードの最終ビルド日: 2024-11-06

build.gradle.kts

// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.android) apply false
}

app/build.gradle.kts

plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
}

android {
    namespace = "jp.aosystem.barcodereader"
    compileSdk = 35

    defaultConfig {
        applicationId = "jp.aosystem.barcodereader"
        minSdk = 26     //LocalDateTime.now()使用の為
        targetSdk = 35

        versionCode = 26
        versionName = "1.23.1"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = "11"
    }
}

dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.appcompat)
    implementation(libs.material)
    implementation(libs.androidx.activity)
    implementation(libs.androidx.constraintlayout)
    implementation(libs.play.services.ads)
    implementation(libs.journeyapps.zxing.android.embedded)  // QR code
    implementation(libs.google.zxing.core)
    implementation(libs.play.services.oss.licenses)  // QR code

    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
}

gradle/libs.versions.toml

[versions]
agp = "8.7.2"
kotlin = "2.0.0"
coreKtx = "1.15.0"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
appcompat = "1.7.0"
material = "1.12.0"
activity = "1.9.3"
constraintlayout = "2.2.0"
playServicesAds = "23.5.0"
journeyapps-zxing-android-embedded = "4.3.0"
google-zxing-core = "3.5.3"
playServicesOssLicenses = "17.1.0"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
play-services-ads = { module = "com.google.android.gms:play-services-ads", version.ref = "playServicesAds" }
journeyapps-zxing-android-embedded = { module = "com.journeyapps:zxing-android-embedded", version.ref = "journeyapps-zxing-android-embedded" }
google-zxing-core = { module = "com.google.zxing:core", version.ref = "google-zxing-core" }
play-services-oss-licenses = { group = "com.google.android.gms", name = "play-services-oss-licenses", version.ref = "playServicesOssLicenses" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

app/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:theme="@style/Theme.Barcodereader"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.journeyapps.barcodescanner.CaptureActivity"
            android:screenOrientation="fullSensor"
            tools:replace="screenOrientation">
        </activity>
        <activity android:name=".SettingActivity"
            android:theme="@style/Theme.Barcodereader"
            android:exported="true">
        </activity>
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-0000000000000000~0000000000">
        </meta-data>
    </application>

</manifest>

app/src/main/java/jp/aosystem/barcodereader/MainActivity.kt

package jp.aosystem.barcodereader

import android.app.Activity
import android.app.AlertDialog
import android.content.*
import android.content.res.Configuration
import android.graphics.Color
import android.hardware.camera2.CameraManager
import android.net.Uri
import android.os.Bundle
import android.os.LocaleList
import android.util.DisplayMetrics
import android.view.Gravity
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds
import com.google.zxing.integration.android.IntentIntegrator
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
import kotlin.collections.ArrayList

class MainActivity : AppCompatActivity() {
    private lateinit var vLayoutBase: LinearLayout
    private lateinit var vTextLightOff: TextView
    private lateinit var vTextLightOn: TextView
    private lateinit var vTextSetting: TextView
    private lateinit var vTextScan: TextView
    private lateinit var vTextCopy: TextView
    private lateinit var vTextSend: TextView
    private lateinit var vTextDelete: TextView
    private lateinit var vTextCopyLast: TextView
    private lateinit var vTextSendLast: TextView
    private lateinit var vTextBrowserLast: TextView
    private lateinit var vTextDeleteLast: TextView
    private lateinit var vEditText1: EditText
    private lateinit var vAdContainer: LinearLayout
    private var continuousScan: Int = 0
    private var beepSoundWhenScan: Int = 0
    private var fixedOrientation: Int = 0
    private var themeNumber: Int = 0
    private var localeLanguage: String = ""
    private var cameraManager: CameraManager? = null
    private var cameraId: String? = null

    //adMob
    private lateinit var adView: AdView     //adMob
    private val adSize: AdSize
        get() {
            val display = windowManager.defaultDisplay
            val outMetrics = DisplayMetrics()
            display.getMetrics(outMetrics)
            val density = outMetrics.density
            var adWidthPixels = this.vAdContainer.width.toFloat()
            if (adWidthPixels == 0f) {
                adWidthPixels = outMetrics.widthPixels.toFloat()
            }
            val adWidth = (adWidthPixels / density).toInt()
            return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, adWidth)
        }

    companion object {
        private const val AD_UNIT_ID: String = "ca-app-pub-0000000000000000/0000000000"     //adMob
        private const val READ_TEXT: String = "readText"
        internal const val SETTINGS: String = "settings"
        internal const val CONTINUOUS_SCAN: String = "continuousScan"
        internal const val BEEP_SOUND_WHEN_SCAN: String = "beepSoundWhenScan"
        internal const val FIXED_ORIENTATION: String = "fixedOrientation"
        internal const val THEME_NUMBER: String = "themeNumber"
        internal const val LOCALE_LANGUAGE: String = "localeLanguage"
        private const val SEPARATOR: String = "%SePaRaToR%"   //ユニークな文字列
    }
    private var scanIntegrator: IntentIntegrator? = null
    private var lastToast: Toast? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        supportActionBar?.hide()    //タイトルバー非表示
        //
        this.vLayoutBase = findViewById(R.id.layoutBase)
        this.vTextLightOff = findViewById(R.id.textLightOff)
        this.vTextLightOn = findViewById(R.id.textLightOn)
        this.vTextSetting = findViewById(R.id.textSettings)
        this.vTextScan = findViewById(R.id.textScan)
        this.vTextCopy = findViewById(R.id.textCopy)
        this.vTextSend = findViewById(R.id.textSend)
        this.vTextDelete = findViewById(R.id.textDelete)
        this.vTextCopyLast = findViewById(R.id.textCopyLast)
        this.vTextSendLast = findViewById(R.id.textSendLast)
        this.vTextBrowserLast = findViewById(R.id.textBrowserLast)
        this.vTextDeleteLast = findViewById(R.id.textDeleteLast)
        this.vEditText1 = findViewById(R.id.editText1)
        this.vAdContainer = findViewById(R.id.adContainer)
        this.vTextLightOff.setOnClickListener {
            this.onClickLightOff()
        }
        this.vTextLightOn.setOnClickListener {
            this.onClickLightOn()
        }
        this.vTextSetting.setOnClickListener {
            this.onClickSetting()
        }
        this.vTextScan.setOnClickListener {
            this.onClickButtonScan()
        }
        this.vTextCopy.setOnClickListener {
            this.onClickButtonCopy()
        }
        this.vTextSend.setOnClickListener {
            this.onClickButtonSend()
        }
        this.vTextDelete.setOnClickListener {
            this.onClickButtonDelete()
        }
        this.vTextCopyLast.setOnClickListener {
            this.onClickButtonCopyLast()
        }
        this.vTextSendLast.setOnClickListener {
            this.onClickButtonSendLast()
        }
        this.vTextBrowserLast.setOnClickListener {
            this.onClickButtonBrowserLast()
        }
        this.vTextDeleteLast.setOnClickListener {
            this.onClickButtonDeleteLast()
        }
        //config load
        this.loadContinuousScan()
        this.loadBeepSoundWhenScan()
        this.loadFixedOrientation()
        this.loadThemeNumber()
        this.setTheme()
        this.resultTextColor()
        this.vEditText1.setText(this.loadReadText().replace(SEPARATOR,"\n"), TextView.BufferType.NORMAL)
        // カメラマネージャーを初期化
        cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
        try {
            cameraId = cameraManager!!.cameraIdList[0]
        } catch (_: Exception) {
        }
        //adMob
        MobileAds.initialize(this) {}
        this.adView = AdView(this)
        this.vAdContainer.addView(this.adView)
        this.adView.adUnitId = AD_UNIT_ID
        this.adView.setAdSize(this.adSize)
        val adRequest = AdRequest.Builder().build()
        this.adView.loadAd(adRequest)
    }

    override fun onStop() {
        super.onStop()
        this.onClickLightOff()
    }

    private fun resultTextColor() {
        val clr1: Int = if (this.themeNumber == 0) Color.rgb(238,238,238) else Color.rgb(34,34,34)
        this.vLayoutBase.setBackgroundColor(clr1)
        val clr2: Int = if (this.themeNumber == 0) Color.rgb(255,255,255) else Color.rgb(0,0,0)
        this.vEditText1.setBackgroundColor(clr2)
    }

    private fun onClickLightOff() {
        try {
            cameraManager!!.setTorchMode(cameraId!!, false)
        } catch (_: Exception) {
        }
    }

    private fun onClickLightOn() {
        try {
            cameraManager!!.setTorchMode(cameraId!!, true)
        } catch (_: Exception) {
        }
    }

    private fun onClickSetting() {
        val intent = Intent(applicationContext, SettingActivity::class.java)
        intent.putExtra(CONTINUOUS_SCAN, this.continuousScan)
        intent.putExtra(BEEP_SOUND_WHEN_SCAN, this.beepSoundWhenScan)
        intent.putExtra(FIXED_ORIENTATION, this.fixedOrientation)
        intent.putExtra(THEME_NUMBER, this.themeNumber)
        intent.putExtra(LOCALE_LANGUAGE, this.localeLanguage)
        this.settingStartForResult.launch(intent)
    }
    private val settingStartForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK && result.data != null) {
            val intent: Intent = result.data!!
            //設定の戻り
            var reCreateFlag: Boolean = false
            val lastContinuousScan: Int = this.continuousScan
            this.continuousScan = intent.getIntExtra(CONTINUOUS_SCAN, 0)
            if (lastContinuousScan != this.continuousScan) {
                this.saveContinuousScan()
            }
            //
            val lastBeepSoundWhenScan: Int = this.beepSoundWhenScan
            this.beepSoundWhenScan = intent.getIntExtra(BEEP_SOUND_WHEN_SCAN, 0)
            if (lastBeepSoundWhenScan != this.beepSoundWhenScan) {
                this.saveBeepSoundWhenScan()
            }
            //
            val lastFixedOrientation: Int = this.fixedOrientation
            this.fixedOrientation = intent.getIntExtra(FIXED_ORIENTATION, 0)
            if (lastFixedOrientation != this.fixedOrientation) {
                this.saveFixedOrientation()
            }
            //
            val lastThemeNumber: Int = this.themeNumber
            this.themeNumber = intent.getIntExtra(THEME_NUMBER, 0)
            if (lastThemeNumber != this.themeNumber) {
                this.saveThemeNumber()
                reCreateFlag = true
            }
            //
            val lastLocaleLanguage = this.localeLanguage
            this.localeLanguage = intent.getStringExtra(LOCALE_LANGUAGE) ?: ""
            if (this.localeLanguage != lastLocaleLanguage) {
                this.saveLocaleLanguage()
                reCreateFlag = true
            }
            if (reCreateFlag) {
                recreate()
            }
        }
    }

    private fun onClickButtonScan() {
        this.scanIntegrator = IntentIntegrator(this)
        this.scanIntegrator?.setPrompt("Scan a code")
        this.scanIntegrator?.setBeepEnabled(this.beepSoundWhenScan == 1)    //読み取り後にビープ音
        this.scanIntegrator?.setOrientationLocked(this.fixedOrientation == 1)  //画面の回転 false:回転 true:固定 無指定:固定
        this.scanIntegrator?.setBarcodeImageEnabled(false)
        this.scanIntegrator?.initiateScan()   //スキャン開始(アクティビティ生成)
    }
    // 読み取り後に呼ばれるメソッド
    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        // 結果の取得
        val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent)
        if (result != null) {
            if (result.contents == null) {  //取得した値
                Toast(this).showCustomToast("Cancelled", this)
            } else {
                val dateTime: LocalDateTime = LocalDateTime.now()
                val formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")
                val dt: String = dateTime.format(formatter)
                val str: String = dt + "," + result.formatName + "," + result.contents
                Toast(this).showCustomToast(result.contents, this)
                var results: String = this.loadReadText()
                results += if (results == "") str else SEPARATOR + str
                this.saveReadText(results)
                this.vEditText1.setText(results.replace(SEPARATOR,"\n"), TextView.BufferType.NORMAL)
                if (this.continuousScan == 1) {
                    this.scanIntegrator?.initiateScan()   //スキャン開始(アクティビティ生成)
                }
            }
        } else {
            super.onActivityResult(requestCode, resultCode, intent)
        }
    }

    //テキストを保存
    private fun saveReadText(str: String) {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putString(READ_TEXT, str)
            apply()
        }
    }

    //テキストを読み出し
    private fun loadReadText(): String {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        return pref.getString(READ_TEXT, "").toString()
    }

    private fun onClickButtonCopy() {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringCopied: String = getString(R.string.copied)
        val rStringButtonCopy: String = getString(R.string.buttonCopy)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonCopy)
            setMessage("")
            setPositiveButton(rStringOk) { _, _ ->
                val results: String = this@MainActivity.loadReadText()
                val mManager: ClipboardManager =
                    applicationContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                val clip: ClipData =
                    ClipData.newPlainText("label", this@MainActivity.toCsv(results))
                mManager.setPrimaryClip(clip)
                Toast(this@MainActivity).showCustomToast(rStringCopied, this@MainActivity)
            }
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    private fun onClickButtonSend() {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringButtonSend: String = getString(R.string.buttonSend)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonSend)
            setMessage("")
            setPositiveButton(rStringOk) { _, _ ->
                val results: String = this@MainActivity.loadReadText()
                val csv: String = this@MainActivity.toCsv(results)
                val sendIntent: Intent = Intent().apply {
                    action = Intent.ACTION_SEND
                    putExtra(Intent.EXTRA_TEXT, csv)
                    type = "text/plain"
                }
                val shareIntent = Intent.createChooser(sendIntent, null)
                startActivity(shareIntent)
            }
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    private fun onClickButtonDelete() {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringDeleted: String = getString(R.string.deleted)
        val rStringButtonDelete: String = getString(R.string.buttonDelete)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonDelete)
            setMessage("")
            setPositiveButton(rStringOk) { _, _ ->
                this@MainActivity.vEditText1.text = null
                this@MainActivity.saveReadText("")
                Toast(this@MainActivity).showCustomToast(rStringDeleted, this@MainActivity)
            }
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    private fun onClickButtonCopyLast() {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringCopied: String = getString(R.string.copied)
        val rStringButtonCopyLast: String = getString(R.string.buttonCopyLast)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonCopyLast)
            setMessage("")
            setPositiveButton(rStringOk) { _, _ ->
                val results: String = this@MainActivity.readLast()
                val mManager: ClipboardManager =
                    applicationContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                val clip: ClipData = ClipData.newPlainText("label", results)
                mManager.setPrimaryClip(clip)
                Toast(this@MainActivity).showCustomToast(rStringCopied, this@MainActivity)
            }
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    private fun onClickButtonSendLast() {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringButtonSendLast: String = getString(R.string.buttonSendLast)
        //
        val results: String = this.readLast()
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonSendLast)
            setMessage(results)
            setPositiveButton(rStringOk) { _, _ ->
                val sendIntent: Intent = Intent().apply {
                    action = Intent.ACTION_SEND
                    putExtra(Intent.EXTRA_TEXT, results)
                    type = "text/plain"
                }
                val shareIntent = Intent.createChooser(sendIntent, null)
                startActivity(shareIntent)
            }
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    private fun onClickButtonBrowserLast() {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringButtonBrowserLast: String = getString(R.string.buttonBrowserLast)
        //
        val results: String = this.readLast()
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonBrowserLast)
            setMessage(results)
            setPositiveButton(rStringOk) { _, _ ->
                if (results.startsWith("http://") || results.startsWith("https://")) {
                    val uri: Uri? = Uri.parse(results)
                    if (uri != null) {
                        val intent = Intent(Intent.ACTION_VIEW, uri)
                        startActivity(intent)
                    }
                } else {
                    val sendIntent: Intent = Intent().apply {
                        action = Intent.ACTION_SEND
                        putExtra(Intent.EXTRA_TEXT, results)
                        type = "text/plain"
                    }
                    val shareIntent = Intent.createChooser(sendIntent, null)
                    startActivity(shareIntent)
                }
            }
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    private fun onClickButtonDeleteLast() {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringDeleted: String = getString(R.string.deleted)
        val rStringButtonDeleteLast: String = getString(R.string.buttonDeleteLast)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonDeleteLast)
            setMessage("")
            setPositiveButton(rStringOk) { _, _ ->
                this@MainActivity.deleteLast()
                Toast(this@MainActivity).showCustomToast(rStringDeleted, this@MainActivity)
            }
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    private fun readLast(): String {
        val org: String = this@MainActivity.loadReadText()
        if (org == "") {
            return ""
        }
        val ary: ArrayList<String> = if (Regex(SEPARATOR).containsMatchIn(org)) {
            org.split(SEPARATOR) as ArrayList<String>
        } else {
            arrayListOf(org)
        }
        val last: String = ary.last()
        val ary2: ArrayList<String> = last.split(",", limit = 3) as ArrayList<String>
        return ary2.getOrElse(2){""}
    }

    private fun deleteLast() {
        val org: String = this@MainActivity.loadReadText()
        if (org == "") {
            return
        }
        val ary: ArrayList<String> = if (Regex(SEPARATOR).containsMatchIn(org)) {
            org.split(SEPARATOR) as ArrayList<String>
        } else {
            arrayListOf(org)
        }
        var result: String = ""
        var last: String = ""
        ary.forEach{ s1 ->
            if (last != "") {
                result += if (result == "") last else SEPARATOR + last
            }
            last = s1
        }
        this@MainActivity.saveReadText(result)
        this@MainActivity.vEditText1.setText(result.replace(SEPARATOR,"\n"), TextView.BufferType.NORMAL)
    }

    private fun toCsv(str: String): String {
        if (str == "") {
            return ""
        }
        var result: String = ""
        val ary: ArrayList<String> = str.split(SEPARATOR) as ArrayList<String>
        ary.forEach{ s1 ->
            val ary2: ArrayList<String> = s1.split(",",limit = 3) as ArrayList<String>
            result += "\"" + ary2.getOrElse(0){""} + "\",\"" + ary2.getOrElse(1){""} + "\",\"" + ary2.getOrElse(2){""}.replace("\"","\"\"") + "\"\n"
        }
        return result
    }

    //custom Toast
    private fun Toast.showCustomToast(message: String, activity: Activity) {
        if (this@MainActivity.lastToast != null) {  //前回のToastが残っていたら削除
            this@MainActivity.lastToast!!.cancel()
            this@MainActivity.lastToast = null
        }
        val layout = activity.layoutInflater.inflate (
            R.layout.custom_toast_layout,
            activity.findViewById(R.id.toast_container)
        )
        // set the text of the TextView of the message
        val textView = layout.findViewById<TextView>(R.id.toast_text)
        textView.text = message
        // use the application extension function
        this.apply {
            setGravity(Gravity.BOTTOM, 0, 40)
            duration = Toast.LENGTH_SHORT
            view = layout
            show()
        }
        this@MainActivity.lastToast = this
    }

    //--------------------------------------------------------------------------------

    //連続読取を保存
    private fun saveContinuousScan() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putInt(CONTINUOUS_SCAN, this@MainActivity.continuousScan)
            apply()
        }
    }

    //連続読取を読み出し
    private fun loadContinuousScan() {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.continuousScan = pref.getInt(CONTINUOUS_SCAN, 0)
    }

    //読取時ビープ音を保存
    private fun saveBeepSoundWhenScan() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putInt(BEEP_SOUND_WHEN_SCAN, this@MainActivity.beepSoundWhenScan)
            apply()
        }
    }

    //読取時ビープ音を読み出し
    private fun loadBeepSoundWhenScan() {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.beepSoundWhenScan = pref.getInt(BEEP_SOUND_WHEN_SCAN, 0)
    }

    //縦横固定を保存
    private fun saveFixedOrientation() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putInt(FIXED_ORIENTATION, this@MainActivity.fixedOrientation)
            apply()
        }
    }

    //縦横固定を読み出し
    private fun loadFixedOrientation() {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.fixedOrientation = pref.getInt(FIXED_ORIENTATION, 0)
    }

    //テーマを保存
    private fun saveThemeNumber() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putInt(THEME_NUMBER, this@MainActivity.themeNumber)
            apply()
        }
    }

    //テーマを読み出し
    private fun loadThemeNumber() {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.themeNumber = pref.getInt(THEME_NUMBER, 0)
    }

    //テーマを設定
    private fun setTheme() {
        when (this.themeNumber) {
            0 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            1 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
        }
    }

    //--------------------------------------------------------------------------------

    //localeLanguageを保存
    private fun saveLocaleLanguage() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putString(LOCALE_LANGUAGE, this@MainActivity.localeLanguage)
            apply()
        }
    }

    //言語設定
    override fun attachBaseContext(base: Context) {
        val pref = base.getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.localeLanguage = pref.getString(LOCALE_LANGUAGE, "") ?: ""
        val loc: Locale? = if (this.localeLanguage != "") Locale(this.localeLanguage) else null
        if (loc != null) {
            val res = base.resources
            val config = Configuration(res.configuration)
            val localeList = LocaleList(loc)
            LocaleList.setDefault(localeList)
            config.setLocales(localeList)
            super.attachBaseContext(base.createConfigurationContext(config))
        } else {
            super.attachBaseContext(base)
        }
    }

    //--------------------------------------------------------------------------------

}

app/src/main/java/jp/aosystem/barcodereader/SettingActivity.kt

package jp.aosystem.barcodereader

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import android.os.LocaleList
import android.view.View
import android.widget.RadioButton
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import java.util.*

class SettingActivity : AppCompatActivity() {

    private lateinit var vTextCancel: TextView
    private lateinit var vTextApply: TextView
    private lateinit var vSwitchContinuousScan: SwitchCompat
    private lateinit var vSwitchBeepSoundWhenScan: SwitchCompat
    private lateinit var vSwitchFixedOrientation: SwitchCompat
    private lateinit var vRadioLanguageSystem: RadioButton
    private lateinit var vRadioLanguageEn: RadioButton
    private lateinit var vRadioLanguageBg: RadioButton
    private lateinit var vRadioLanguageCs: RadioButton
    private lateinit var vRadioLanguageDa: RadioButton
    private lateinit var vRadioLanguageDe: RadioButton
    private lateinit var vRadioLanguageEl: RadioButton
    private lateinit var vRadioLanguageEs: RadioButton
    private lateinit var vRadioLanguageEt: RadioButton
    private lateinit var vRadioLanguageFi: RadioButton
    private lateinit var vRadioLanguageFr: RadioButton
    private lateinit var vRadioLanguageHu: RadioButton
    private lateinit var vRadioLanguageIt: RadioButton
    private lateinit var vRadioLanguageJa: RadioButton
    private lateinit var vRadioLanguageLt: RadioButton
    private lateinit var vRadioLanguageLv: RadioButton
    private lateinit var vRadioLanguageNl: RadioButton
    private lateinit var vRadioLanguagePl: RadioButton
    private lateinit var vRadioLanguagePt: RadioButton
    private lateinit var vRadioLanguageRo: RadioButton
    private lateinit var vRadioLanguageRu: RadioButton
    private lateinit var vRadioLanguageSk: RadioButton
    private lateinit var vRadioLanguageSv: RadioButton
    private lateinit var vRadioLanguageZh: RadioButton
    private lateinit var vSwitchTheme: SwitchCompat


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_setting)
        supportActionBar?.hide()    //タイトルバー非表示
        //
        this.vTextCancel = findViewById(R.id.textCancel)
        this.vTextApply = findViewById(R.id.textApply)
        this.vSwitchContinuousScan = findViewById(R.id.switchContinuousScan)
        this.vSwitchBeepSoundWhenScan = findViewById(R.id.switchBeepSoundWhenScan)
        this.vSwitchFixedOrientation = findViewById(R.id.switchFixedOrientation)
        this.vRadioLanguageSystem = findViewById(R.id.radioLanguageSystem)
        this.vRadioLanguageEn = findViewById(R.id.radioLanguageEn)
        this.vRadioLanguageBg = findViewById(R.id.radioLanguageBg)
        this.vRadioLanguageCs = findViewById(R.id.radioLanguageCs)
        this.vRadioLanguageDa = findViewById(R.id.radioLanguageDa)
        this.vRadioLanguageDe = findViewById(R.id.radioLanguageDe)
        this.vRadioLanguageEl = findViewById(R.id.radioLanguageEl)
        this.vRadioLanguageEs = findViewById(R.id.radioLanguageEs)
        this.vRadioLanguageEt = findViewById(R.id.radioLanguageEt)
        this.vRadioLanguageFi = findViewById(R.id.radioLanguageFi)
        this.vRadioLanguageFr = findViewById(R.id.radioLanguageFr)
        this.vRadioLanguageHu = findViewById(R.id.radioLanguageHu)
        this.vRadioLanguageIt = findViewById(R.id.radioLanguageIt)
        this.vRadioLanguageJa = findViewById(R.id.radioLanguageJa)
        this.vRadioLanguageLt = findViewById(R.id.radioLanguageLt)
        this.vRadioLanguageLv = findViewById(R.id.radioLanguageLv)
        this.vRadioLanguageNl = findViewById(R.id.radioLanguageNl)
        this.vRadioLanguagePl = findViewById(R.id.radioLanguagePl)
        this.vRadioLanguagePt = findViewById(R.id.radioLanguagePt)
        this.vRadioLanguageRo = findViewById(R.id.radioLanguageRo)
        this.vRadioLanguageRu = findViewById(R.id.radioLanguageRu)
        this.vRadioLanguageSk = findViewById(R.id.radioLanguageSk)
        this.vRadioLanguageSv = findViewById(R.id.radioLanguageSv)
        this.vRadioLanguageZh = findViewById(R.id.radioLanguageZh)
        this.vSwitchTheme = findViewById(R.id.switchTheme)

        // データ受け取り
        val intent = this.intent
        val continuousScan: Int = intent.getIntExtra(MainActivity.CONTINUOUS_SCAN,0)
        this.vSwitchContinuousScan.isChecked = continuousScan != 0
        val beepSoundWhenScan: Int = intent.getIntExtra(MainActivity.BEEP_SOUND_WHEN_SCAN,0)
        this.vSwitchBeepSoundWhenScan.isChecked = beepSoundWhenScan != 0
        val fixedOrientation: Int = intent.getIntExtra(MainActivity.FIXED_ORIENTATION,0)
        this.vSwitchFixedOrientation.isChecked = fixedOrientation != 0
        val themeNumber: Int = intent.getIntExtra(MainActivity.THEME_NUMBER,0)
        this.vSwitchTheme.isChecked = themeNumber != 0
        val localeLanguage: String = intent.getStringExtra(MainActivity.LOCALE_LANGUAGE) ?: ""
        when (localeLanguage) {
            "en" -> this.vRadioLanguageEn.isChecked = true
            "bg" -> this.vRadioLanguageBg.isChecked = true
            "cs" -> this.vRadioLanguageCs.isChecked = true
            "da" -> this.vRadioLanguageDa.isChecked = true
            "de" -> this.vRadioLanguageDe.isChecked = true
            "el" -> this.vRadioLanguageEl.isChecked = true
            "es" -> this.vRadioLanguageEs.isChecked = true
            "et" -> this.vRadioLanguageEt.isChecked = true
            "fi" -> this.vRadioLanguageFi.isChecked = true
            "fr" -> this.vRadioLanguageFr.isChecked = true
            "hu" -> this.vRadioLanguageHu.isChecked = true
            "it" -> this.vRadioLanguageIt.isChecked = true
            "ja" -> this.vRadioLanguageJa.isChecked = true
            "lt" -> this.vRadioLanguageLt.isChecked = true
            "lv" -> this.vRadioLanguageLv.isChecked = true
            "nl" -> this.vRadioLanguageNl.isChecked = true
            "pl" -> this.vRadioLanguagePl.isChecked = true
            "pt" -> this.vRadioLanguagePt.isChecked = true
            "ro" -> this.vRadioLanguageRo.isChecked = true
            "ru" -> this.vRadioLanguageRu.isChecked = true
            "sk" -> this.vRadioLanguageSk.isChecked = true
            "sv" -> this.vRadioLanguageSv.isChecked = true
            "zh" -> this.vRadioLanguageZh.isChecked = true
            else -> this.vRadioLanguageSystem.isChecked = true
        }
        //
        supportActionBar?.hide()    //タイトルバー非表示
    }

    fun onClickApply(v: View) {
        val continuousScan = if (this.vSwitchContinuousScan.isChecked) 1 else 0
        val beepSoundWhenScan = if (this.vSwitchBeepSoundWhenScan.isChecked) 1 else 0
        val fixedOrientation = if (this.vSwitchFixedOrientation.isChecked) 1 else 0
        val themeNumber = if (this.vSwitchTheme.isChecked) 1 else 0
        var localeLanguage: String = ""
        if (this.vRadioLanguageEn.isChecked) {
            localeLanguage = "en"
        } else if (this.vRadioLanguageBg.isChecked) {
            localeLanguage = "bg"
        } else if (this.vRadioLanguageCs.isChecked) {
            localeLanguage = "cs"
        } else if (this.vRadioLanguageDa.isChecked) {
            localeLanguage = "da"
        } else if (this.vRadioLanguageDe.isChecked) {
            localeLanguage = "de"
        } else if (this.vRadioLanguageEl.isChecked) {
            localeLanguage = "el"
        } else if (this.vRadioLanguageEs.isChecked) {
            localeLanguage = "es"
        } else if (this.vRadioLanguageEt.isChecked) {
            localeLanguage = "et"
        } else if (this.vRadioLanguageFi.isChecked) {
            localeLanguage = "fi"
        } else if (this.vRadioLanguageFr.isChecked) {
            localeLanguage = "fr"
        } else if (this.vRadioLanguageHu.isChecked) {
            localeLanguage = "hu"
        } else if (this.vRadioLanguageIt.isChecked) {
            localeLanguage = "it"
        } else if (this.vRadioLanguageJa.isChecked) {
            localeLanguage = "ja"
        } else if (this.vRadioLanguageLt.isChecked) {
            localeLanguage = "lt"
        } else if (this.vRadioLanguageLv.isChecked) {
            localeLanguage = "lv"
        } else if (this.vRadioLanguageNl.isChecked) {
            localeLanguage = "nl"
        } else if (this.vRadioLanguagePl.isChecked) {
            localeLanguage = "pl"
        } else if (this.vRadioLanguagePt.isChecked) {
            localeLanguage = "pt"
        } else if (this.vRadioLanguageRo.isChecked) {
            localeLanguage = "ro"
        } else if (this.vRadioLanguageRu.isChecked) {
            localeLanguage = "ru"
        } else if (this.vRadioLanguageSk.isChecked) {
            localeLanguage = "sk"
        } else if (this.vRadioLanguageSv.isChecked) {
            localeLanguage = "sv"
        } else if (this.vRadioLanguageZh.isChecked) {
            localeLanguage = "zh"
        }
        val intent = Intent()
        intent.putExtra(MainActivity.CONTINUOUS_SCAN, continuousScan)
        intent.putExtra(MainActivity.BEEP_SOUND_WHEN_SCAN, beepSoundWhenScan)
        intent.putExtra(MainActivity.FIXED_ORIENTATION, fixedOrientation)
        intent.putExtra(MainActivity.THEME_NUMBER, themeNumber)
        intent.putExtra(MainActivity.LOCALE_LANGUAGE, localeLanguage)
        setResult(Activity.RESULT_OK, intent)
        finish()
    }

    fun onClickCancel(v: View) {
        val intent = Intent()
        setResult(Activity.RESULT_CANCELED, intent)
        finish()
    }

    //--------------------------------------------------------------------------------

    //言語設定
    override fun attachBaseContext(base: Context) {
        val pref = base.getSharedPreferences(MainActivity.SETTINGS, Context.MODE_PRIVATE)
        val localeLanguage: String = pref.getString(MainActivity.LOCALE_LANGUAGE, "") ?: ""
        val loc: Locale? = if (localeLanguage != "") Locale(localeLanguage) else null
        if (loc != null) {
            val res = base.resources
            val config = Configuration(res.configuration)
            val localeList = LocaleList(loc)
            LocaleList.setDefault(localeList)
            config.setLocales(localeList)
            super.attachBaseContext(base.createConfigurationContext(config))
        } else {
            super.attachBaseContext(base)
        }
    }

    //--------------------------------------------------------------------------------

}

app/src/main/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/layoutBase"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingBottom="20dp">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="48dip"
                    android:layout_marginTop="1dp"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/textLightOff"
                        android:layout_width="wrap_content"
                        android:layout_height="48dip"
                        android:layout_marginStart="1dp"
                        android:layout_weight="1"
                        android:background="@color/buttonColor3"
                        android:gravity="center"
                        android:minHeight="48dip"
                        android:text="@string/lightOff" />

                    <TextView
                        android:id="@+id/textLightOn"
                        android:layout_width="wrap_content"
                        android:layout_height="48dip"
                        android:layout_marginStart="1dp"
                        android:layout_weight="1"
                        android:background="@color/buttonColor3"
                        android:gravity="center"
                        android:minHeight="48dip"
                        android:text="@string/lightOn" />

                    <TextView
                        android:id="@+id/textSettings"
                        android:layout_width="wrap_content"
                        android:layout_height="48dip"
                        android:layout_marginStart="1dp"
                        android:layout_marginEnd="1dp"
                        android:layout_weight="1"
                        android:background="@color/buttonColor3"
                        android:gravity="center"
                        android:minHeight="48dip"
                        android:text="@string/settings" />
                </LinearLayout>

                <TextView
                    android:id="@+id/textScan"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="1dp"
                    android:layout_marginTop="1dp"
                    android:layout_marginEnd="1dp"
                    android:layout_weight="1"
                    android:background="@color/buttonColor1"
                    android:gravity="center"
                    android:minHeight="96dip"
                    android:text="@string/buttonScan" />

                <TextView
                    android:id="@+id/textCopy"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="1dp"
                    android:layout_marginTop="1dp"
                    android:layout_marginEnd="1dp"
                    android:layout_weight="1"
                    android:background="@color/buttonColor2"
                    android:gravity="center"
                    android:minHeight="56dp"
                    android:text="@string/buttonCopy" />

                <TextView
                    android:id="@+id/textSend"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="1dp"
                    android:layout_marginTop="1dp"
                    android:layout_marginEnd="1dp"
                    android:layout_weight="1"
                    android:background="@color/buttonColor2"
                    android:gravity="center"
                    android:minHeight="56dp"
                    android:text="@string/buttonSend" />

                <TextView
                    android:id="@+id/textDelete"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="1dp"
                    android:layout_marginTop="1dp"
                    android:layout_marginEnd="1dp"
                    android:layout_weight="1"
                    android:background="@color/buttonColor2"
                    android:gravity="center"
                    android:minHeight="56dp"
                    android:text="@string/buttonDelete" />

                <TextView
                    android:id="@+id/textCopyLast"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="1dp"
                    android:layout_marginTop="1dp"
                    android:layout_marginEnd="1dp"
                    android:layout_weight="1"
                    android:background="@color/buttonColor3"
                    android:gravity="center"
                    android:minHeight="56dp"
                    android:text="@string/buttonCopyLast" />

                <TextView
                    android:id="@+id/textSendLast"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="1dp"
                    android:layout_marginTop="1dp"
                    android:layout_marginEnd="1dp"
                    android:layout_weight="1"
                    android:background="@color/buttonColor3"
                    android:gravity="center"
                    android:minHeight="56dp"
                    android:text="@string/buttonSendLast" />

                <TextView
                    android:id="@+id/textBrowserLast"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="1dp"
                    android:layout_marginTop="1dp"
                    android:layout_marginEnd="1dp"
                    android:layout_weight="1"
                    android:background="@color/buttonColor3"
                    android:gravity="center"
                    android:minHeight="56dp"
                    android:text="@string/buttonBrowserLast" />

                <TextView
                    android:id="@+id/textDeleteLast"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="1dp"
                    android:layout_marginTop="1dp"
                    android:layout_marginEnd="1dp"
                    android:layout_weight="1"
                    android:background="@color/buttonColor3"
                    android:gravity="center"
                    android:minHeight="56dp"
                    android:text="@string/buttonDeleteLast" />

                <EditText
                    android:id="@+id/editText1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="15dp"
                    android:layout_marginStart="5dp"
                    android:layout_marginEnd="5dp"
                    android:autofillHints=""
                    android:background="@drawable/border"
                    android:ems="10"
                    android:focusable="false"
                    android:focusableInTouchMode="false"
                    android:gravity="start|top"
                    android:inputType="textMultiLine"
                    android:paddingLeft="5dp"
                    android:paddingTop="2dp"
                    android:paddingRight="5dp"
                    android:paddingBottom="2dp"
                    android:textSize="13sp" />

                <Space
                    android:layout_width="match_parent"
                    android:layout_height="120dp" />

            </LinearLayout>
        </ScrollView>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/adContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent">

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

app/src/main/res/layout/activity_setting.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SettingActivity">

    <LinearLayout
        android:id="@+id/layoutButtons"
        android:layout_width="match_parent"
        android:layout_height="48dip"
        android:layout_marginTop="1dp"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textCancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@color/buttonColor3"
            android:gravity="center"
            android:minHeight="48dip"
            android:onClick="onClickCancel"
            android:text="@string/cancel" />

        <TextView
            android:id="@+id/textApply"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="1dp"
            android:layout_weight="1"
            android:background="@color/buttonColor3"
            android:gravity="center"
            android:minHeight="48dip"
            android:onClick="onClickApply"
            android:text="@string/apply" />

    </LinearLayout>
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/layoutButtons">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:orientation="vertical"
            android:paddingLeft="20dp"
            android:paddingTop="20dp"
            android:paddingRight="20dp"
            android:paddingBottom="50dp">

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switchContinuousScan"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="@string/continuousScan" />

            <View
                android:id="@+id/divider1"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="10dp"
                android:background="?android:attr/listDivider" />

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switchBeepSoundWhenScan"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="@string/BeepSoundWhenScan" />

            <View
                android:id="@+id/divider2"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="10dp"
                android:background="?android:attr/listDivider" />

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switchFixedOrientation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="@string/fixedOrientation" />

            <View
                android:id="@+id/divider3"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="10dp"
                android:background="?android:attr/listDivider" />

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switchTheme"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="@string/darkTheme" />

            <View
                android:id="@+id/divider4"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="10dp"
                android:background="?android:attr/listDivider" />

            <TextView
                android:id="@+id/textLanguage"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:text="@string/language"
                android:textColor="?android:attr/textColorPrimary" />

            <TextView
                android:id="@+id/textView2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                android:text="@string/languageNote" />

            <RadioGroup
                android:layout_width="match_parent"
                android:layout_height="match_parent" >
                <RadioButton
                    android:id="@+id/radioLanguageSystem"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageSystem" />
                <RadioButton
                    android:id="@+id/radioLanguageEn"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageEn" />
                <RadioButton
                    android:id="@+id/radioLanguageBg"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageBg" />
                <RadioButton
                    android:id="@+id/radioLanguageCs"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageCs" />
                <RadioButton
                    android:id="@+id/radioLanguageDa"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageDa" />
                <RadioButton
                    android:id="@+id/radioLanguageDe"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageDe" />
                <RadioButton
                    android:id="@+id/radioLanguageEl"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageEl" />
                <RadioButton
                    android:id="@+id/radioLanguageEs"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageEs" />
                <RadioButton
                    android:id="@+id/radioLanguageEt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageEt" />
                <RadioButton
                    android:id="@+id/radioLanguageFi"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageFi" />
                <RadioButton
                    android:id="@+id/radioLanguageFr"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageFr" />
                <RadioButton
                    android:id="@+id/radioLanguageHu"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageHu" />
                <RadioButton
                    android:id="@+id/radioLanguageIt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageIt" />
                <RadioButton
                    android:id="@+id/radioLanguageJa"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageJa" />
                <RadioButton
                    android:id="@+id/radioLanguageLt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageLt" />
                <RadioButton
                    android:id="@+id/radioLanguageLv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageLv" />
                <RadioButton
                    android:id="@+id/radioLanguageNl"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageNl" />
                <RadioButton
                    android:id="@+id/radioLanguagePl"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languagePl" />
                <RadioButton
                    android:id="@+id/radioLanguagePt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languagePt" />
                <RadioButton
                    android:id="@+id/radioLanguageRo"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageRo" />
                <RadioButton
                    android:id="@+id/radioLanguageRu"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageRu" />
                <RadioButton
                    android:id="@+id/radioLanguageSk"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageSk" />
                <RadioButton
                    android:id="@+id/radioLanguageSv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageSv" />
                <RadioButton
                    android:id="@+id/radioLanguageZh"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageZh" />

            </RadioGroup>


            <View
                android:id="@+id/divider5"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="20dp"
                android:background="?android:attr/listDivider" />

            <Space
                android:layout_width="match_parent"
                android:layout_height="120dp" />


        </LinearLayout>
    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

app/src/main/res/layout/custom_toast_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:id="@+id/toast_container">

	<RelativeLayout
		android:id="@+id/button_parent"
		android:layout_width="match_parent"
		android:layout_height="60dp"
		android:layout_centerHorizontal="true"
		android:layout_centerVertical="true">

		<androidx.cardview.widget.CardView
			android:id="@+id/button_card_parent"
			android:layout_width="match_parent"
			android:layout_height="56dp"
			android:layout_centerHorizontal="true"
			android:layout_centerVertical="true"
			android:layout_marginLeft="25dp"
			app:cardElevation="20dp"
			android:layout_marginRight="25dp"
			app:cardCornerRadius="3dp">

			<RelativeLayout
				android:id="@+id/button_click_parent"
				android:layout_width="match_parent"
				android:layout_height="match_parent"
				android:background="?attr/selectableItemBackground"
				android:clickable="true"
				android:focusable="true">

				<FrameLayout
					android:id="@+id/button_accent_border"
					android:layout_width="5dp"
					android:layout_height="match_parent"
					android:background="#9071c6" />

				<TextView
					android:id="@+id/toast_text"
					android:layout_width="wrap_content"
					android:layout_height="wrap_content"
					android:layout_centerVertical="true"
					android:layout_marginStart="17dp"
					android:ellipsize="end"
					android:lines="1"
					android:textSize="18sp" />

			</RelativeLayout>

		</androidx.cardview.widget.CardView>

	</RelativeLayout>

</RelativeLayout>