ソースコード source code

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

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

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

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.cidr"
    compileSdk = 35

    defaultConfig {
        applicationId = "jp.aosystem.cidr"
        minSdk = 24
        targetSdk = 35

        versionCode = 15
        versionName = "1.13.0"

        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)

}

gradle/libs.versions.toml

[versions]
agp = "8.7.2"
kotlin = "1.9.24"
coreKtx = "1.15.0"
appcompat = "1.7.0"
material = "1.12.0"
activity = "1.9.3"
constraintlayout = "2.2.0"
playServicesAds = "23.5.0"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
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" }

[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:roundIcon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.Cidr"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:windowSoftInputMode="stateVisible|adjustResize"
            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=".SettingActivity"
            android:exported="false">
        </activity>
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-0000000000000000~0000000000" />
    </application>

</manifest>

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

package jp.aosystem.cidr

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.text.Editable
import android.text.TextWatcher
import android.util.DisplayMetrics
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.Spinner
import android.widget.TextView
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 java.util.Locale

class MainActivity : AppCompatActivity() {

    private lateinit var vTextSetting: TextView
    private lateinit var vEditTextIPAddress: EditText
    private lateinit var vSpinner1: Spinner
    private lateinit var vTextResult0: TextView
    private lateinit var vTextResult1: TextView
    private lateinit var vTextResult2: TextView
    private lateinit var vTextResult3: TextView
    private lateinit var vTextResult4: TextView
    private lateinit var vTextResult5: TextView
    private lateinit var vTextResult6: TextView
    private lateinit var vTextResult7: TextView
    private lateinit var vTextResult8: TextView
    private lateinit var vAdContainer: LinearLayout
    private var localeLanguage: String = ""
    private var themeNumber: Int = 0    //0 or 1

    private val netMasks = arrayListOf(
        arrayListOf(0, 0, 0, 0),
        arrayListOf(128, 0, 0, 0),
        arrayListOf(192, 0, 0, 0),
        arrayListOf(224, 0, 0, 0),
        arrayListOf(240, 0, 0, 0),
        arrayListOf(248, 0, 0, 0),
        arrayListOf(252, 0, 0, 0),
        arrayListOf(254, 0, 0, 0),
        arrayListOf(255, 0, 0, 0),
        arrayListOf(255, 128, 0, 0),
        arrayListOf(255, 192, 0, 0),
        arrayListOf(255, 224, 0, 0),
        arrayListOf(255, 240, 0, 0),
        arrayListOf(255, 248, 0, 0),
        arrayListOf(255, 252, 0, 0),
        arrayListOf(255, 254, 0, 0),
        arrayListOf(255, 255, 0, 0),
        arrayListOf(255, 255, 128, 0),
        arrayListOf(255, 255, 192, 0),
        arrayListOf(255, 255, 224, 0),
        arrayListOf(255, 255, 240, 0),
        arrayListOf(255, 255, 248, 0),
        arrayListOf(255, 255, 252, 0),
        arrayListOf(255, 255, 254, 0),
        arrayListOf(255, 255, 255, 0),
        arrayListOf(255, 255, 255, 128),
        arrayListOf(255, 255, 255, 192),
        arrayListOf(255, 255, 255, 224),
        arrayListOf(255, 255, 255, 240),
        arrayListOf(255, 255, 255, 248),
        arrayListOf(255, 255, 255, 252),
        arrayListOf(255, 255, 255, 254),
        arrayListOf(255, 255, 255, 255),
    )

    //adMob
    private lateinit var adView: AdView     //adMob
    private val adSize: AdSize
        get() {
            val density = resources.displayMetrics.density
            var adWidthPixels = this.vAdContainer.width.toFloat()
            if (adWidthPixels == 0f) {
                adWidthPixels = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
                    // APIレベル30以上
                    val windowMetrics = windowManager.currentWindowMetrics
                    windowMetrics.bounds.width().toFloat()
                } else {
                    // APIレベル30未満
                    val display = windowManager.defaultDisplay
                    val outMetrics = DisplayMetrics()
                    display.getMetrics(outMetrics)
                    outMetrics.widthPixels.toFloat()
                }
            }
            val adWidth = (adWidthPixels / density).toInt()
            return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, adWidth)
        }
    private var isAdLoaded: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        supportActionBar?.hide()    //タイトルバー非表示
        //
        this.vTextSetting = findViewById(R.id.textSetting)
        this.vEditTextIPAddress = findViewById(R.id.editTextIPAddress)
        this.vSpinner1 = findViewById(R.id.spinner1)
        this.vTextResult0 = findViewById(R.id.textResult0)
        this.vTextResult1 = findViewById(R.id.textResult1)
        this.vTextResult2 = findViewById(R.id.textResult2)
        this.vTextResult3 = findViewById(R.id.textResult3)
        this.vTextResult4 = findViewById(R.id.textResult4)
        this.vTextResult5 = findViewById(R.id.textResult5)
        this.vTextResult6 = findViewById(R.id.textResult6)
        this.vTextResult7 = findViewById(R.id.textResult7)
        this.vTextResult8 = findViewById(R.id.textResult8)
        this.vAdContainer = findViewById(R.id.adContainer)
        this.vTextSetting.setOnClickListener { this.onClickSetting() }
        //テーマ読み込みと設定
        this.loadThemeNumber()
        this.setTheme()
        this.loadLocaleLanguage()
        //vSpinner1設定
        this.setSpinner()
        //背景タッチでキーボードを隠す
        this.setKeyboardHidingOnFocusLost()
        //イベントリスナー
        this.vEditTextIPAddress.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {
                this@MainActivity.calc()
            }
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            }
        })
        //adMob
        MobileAds.initialize(this) {}
    }

    override fun onResume() {
        super.onResume()
        if (isAdLoaded == false) {
            this@MainActivity.loadAd()
            isAdLoaded = true
        }
    }

    private fun loadAd() {
        if (!::adView.isInitialized) {
            adView = AdView(this).apply {
                adUnitId = ConstValue.AD_UNIT_ID
                setAdSize(this@MainActivity.adSize)
            }
            vAdContainer.addView(adView)
        }
        if (!adView.isLoading) {
            adView.loadAd(AdRequest.Builder().build())
        }
    }

    //背景タッチでテキストエリアからフォーカスを外してキーボードを隠す
    private fun setKeyboardHidingOnFocusLost() {
        val editTexts = listOf(
            vEditTextIPAddress,
        )
        val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        editTexts.forEach { editText ->
            editText.setOnFocusChangeListener { _, hasFocus ->
                if (!hasFocus) {
                    inputMethodManager.hideSoftInputFromWindow(editText.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
                }
            }
        }
    }

    private fun setSpinner() {
        val adapter1 = ArrayAdapter<String>(this, android.R.layout.simple_spinner_item)
        adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        adapter1.add("255.255.255.255 (/32) [1]")
        adapter1.add("255.255.255.254 (/31) [2]")
        adapter1.add("255.255.255.252 (/30) [4]")
        adapter1.add("255.255.255.248 (/29) [8]")
        adapter1.add("255.255.255.240 (/28) [16]")
        adapter1.add("255.255.255.224 (/27) [32]")
        adapter1.add("255.255.255.192 (/26) [64]")
        adapter1.add("255.255.255.128 (/25) [128]")
        adapter1.add("255.255.255.0 (/24) [256]")
        adapter1.add("255.255.254.0 (/23) [512]")
        adapter1.add("255.255.252.0 (/22) [1,024]")
        adapter1.add("255.255.248.0 (/21) [2,048]")
        adapter1.add("255.255.240.0 (/20) [4,096]")
        adapter1.add("255.255.224.0 (/19) [8,192]")
        adapter1.add("255.255.192.0 (/18) [16,384]")
        adapter1.add("255.255.128.0 (/17) [32,768]")
        adapter1.add("255.255.0.0 (/16) [65,536]")
        adapter1.add("255.254.0.0 (/15) [131,072]")
        adapter1.add("255.252.0.0 (/14) [262,144]")
        adapter1.add("255.248.0.0 (/13) [524,288]")
        adapter1.add("255.240.0.0 (/12) [1,048,576]")
        adapter1.add("255.224.0.0 (/11) [2,097,152]")
        adapter1.add("255.192.0.0 (/10) [4,194,304]")
        adapter1.add("255.128.0.0 (/9) [8,388,608]")
        adapter1.add("255.0.0.0 (/8) [16,777,216]")
        adapter1.add("254.0.0.0 (/7) [33,554,432]")
        adapter1.add("252.0.0.0 (/6) [67,108,864]")
        adapter1.add("248.0.0.0 (/5) [134,217,728]")
        adapter1.add("240.0.0.0 (/4) [268,435,456]")
        adapter1.add("224.0.0.0 (/3) [536,870,912]")
        adapter1.add("192.0.0.0 (/2) [1,073,741,824]")
        adapter1.add("128.0.0.0 (/1) [2,147,483,648]")
        this.vSpinner1.adapter = adapter1
        this.vSpinner1.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            // アイテムが選択された時
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                //val spinnerParent = parent as Spinner
                //val item = spinnerParent.selectedItem as String
                this@MainActivity.calc()
            }
            // アイテムが選択されなかった
            override fun onNothingSelected(parent: AdapterView<*>?) {
            }
        }
    }

    private fun calc() {
        var ipAddresses: String = this.vEditTextIPAddress.text.toString()
        if (ipAddresses == "") {
            ipAddresses = "0"
        }
        val ips = "${ipAddresses}.0.0.0.0".split('.')
        val ipAry = arrayListOf(0, 0, 0, 0)
        for (i in 0..3) {
            ipAry[i] = "000${ips[i]}".takeLast(3).toIntOrNull() ?: 0
            if (ipAry[i] < 0) {
                ipAry[i] = 0
            } else if (ipAry[i] > 255) {
                ipAry[i] = 255
            }
        }
        this.vTextResult0.text = "${ipAry[0]}.${ipAry[1]}.${ipAry[2]}.${ipAry[3]}"
        val subnet: Int = this.vSpinner1.selectedItemId.toInt()
        this.calc2(ipAry, subnet);
    }

    private fun calc2(ipAry: MutableList<Int>, subnet: Int) {
        val maskXors = arrayListOf(0, 0, 0, 0)
        val nets = arrayListOf(0, 0, 0, 0)
        val netOrs = arrayListOf(0, 0, 0, 0)
        val masks = arrayListOf(0, 0, 0, 0)
        for (i in 0..3) {
            masks[i] = this.netMasks[32 - subnet][i]
            maskXors[i] = (255 - masks[i])
            nets[i] = ipAry[i].and(masks[i])
            netOrs[i] = nets[i].or(maskXors[i])
        }
        this.vTextResult1.text = "${nets[0]}.${nets[1]}.${nets[2]}.${nets[3]} ~ ${netOrs[0]}.${netOrs[1]}.${netOrs[2]}.${netOrs[3]}"
        this.vTextResult2.text = "${nets[0]}.${nets[1]}.${nets[2]}.${nets[3]}"
        if (nets[3] == netOrs[3]) {
            this.vTextResult3.text = "${nets[0]}.${nets[1]}.${nets[2]}.${nets[3]} (single)"
        } else if ((nets[3] + 1) == netOrs[3]) {
            this.vTextResult3.text = "${nets[0]}.${nets[1]}.${nets[2]}.${nets[3]} ~ ${netOrs[0]}.${netOrs[1]}.${netOrs[2]}.${netOrs[3]} (two)"
        } else {
            this.vTextResult3.text = "${nets[0]}.${nets[1]}.${nets[2]}.${nets[3] + 1} ~ ${netOrs[0]}.${netOrs[1]}.${netOrs[2]}.${netOrs[3] - 1}"
        }
        this.vTextResult4.text = "${netOrs[0]}.${netOrs[1]}.${netOrs[2]}.${netOrs[3]}"
        this.vTextResult5.text = "${nets[0]}.${nets[1]}.${nets[2]}.${nets[3]}/${32 - subnet}"
        this.vTextResult6.text = "${masks[0]}.${masks[1]}.${masks[2]}.${masks[3]}"
        this.vTextResult7.text = "${this.to2(ipAry[0])}.${this.to2(ipAry[1])}.${this.to2(ipAry[2])}.${this.to2(ipAry[3])}"
        this.vTextResult8.text = "${this.to2(masks[0])}.${this.to2(masks[1])}.${this.to2(masks[2])}.${this.to2(masks[3])}"
    }

    private fun to2(num: Int): String {
        val two = num.toString(2)
        return ("00000000" + two).takeLast(8)
    }

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

    private fun onClickSetting() {
        val intent = Intent(applicationContext, SettingActivity::class.java)
        intent.putExtra(ConstValue.LOCALE_LANGUAGE, this.localeLanguage)
        intent.putExtra(ConstValue.THEME_NUMBER, this.themeNumber)
        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 lastLocaleLanguage = this.localeLanguage
            this.localeLanguage = intent.getStringExtra(ConstValue.LOCALE_LANGUAGE) ?: ""
            if (this.localeLanguage != lastLocaleLanguage) {
                this.saveLocaleLanguage()
                reCreateFlag = true
            }
            val lastThemeNumber: Int = this.themeNumber
            this.themeNumber = intent.getIntExtra(ConstValue.THEME_NUMBER, 0)
            if (this.themeNumber != lastThemeNumber) {
                this.saveThemeNumber()
                reCreateFlag = true
            }
            if (reCreateFlag) {
                recreate()
            }
        }
    }

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

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

    //テーマを読み出し
    private fun loadThemeNumber() {
        val pref = getSharedPreferences(ConstValue.SETTINGS, Context.MODE_PRIVATE)
        this.themeNumber = pref.getInt(ConstValue.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(ConstValue.SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putString(ConstValue.LOCALE_LANGUAGE, this@MainActivity.localeLanguage)
            apply()
        }
    }

    //localeLanguageを読み出し
    private fun loadLocaleLanguage() {
        val pref = getSharedPreferences(ConstValue.SETTINGS, Context.MODE_PRIVATE)
        this.localeLanguage = pref.getString(ConstValue.LOCALE_LANGUAGE, "") ?: ""
    }

    // 言語設定
    override fun attachBaseContext(base: Context) {
        val pref = base.getSharedPreferences(ConstValue.SETTINGS, Context.MODE_PRIVATE)
        val localeLanguage = pref.getString(ConstValue.LOCALE_LANGUAGE, "").orEmpty()
        val isValidLocale = localeLanguage.isNotEmpty() && Locale.getAvailableLocales().any { it.language == localeLanguage }
        if (isValidLocale) {
            val locale = Locale(localeLanguage)
            val config = Configuration(base.resources.configuration)
            val localeList = LocaleList(locale)
            LocaleList.setDefault(localeList)
            config.setLocales(localeList)
            super.attachBaseContext(base.createConfigurationContext(config))
        } else {
            super.attachBaseContext(base)
        }
    }

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

}

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

package jp.aosystem.cidr

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.widget.RadioButton
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import java.util.Locale

class SettingActivity : AppCompatActivity() {

    private lateinit var vTextCancel: TextView
    private lateinit var vTextApply: TextView
    private lateinit var vSwitchTheme: SwitchCompat
    private val languageRadioMap: Map<String, Int> = mapOf(
        "en" to R.id.radioLanguageEn,
        "ja" to R.id.radioLanguageJa,
        "" to R.id.radioLanguageSystem
    )

    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.vSwitchTheme = findViewById(R.id.switchTheme)
        // データ受け取りとUIの初期化
        this.setupUIFromIntent()
        // イベントリスナー
        vTextCancel.setOnClickListener { this.onClickCancel() }
        vTextApply.setOnClickListener { this.onClickApply() }
    }

    private fun setupUIFromIntent() {
        val intent = this.intent
        this.vSwitchTheme.isChecked = intent.getIntExtra(ConstValue.THEME_NUMBER, 0) != 0
        val localeLanguage = intent.getStringExtra(ConstValue.LOCALE_LANGUAGE).orEmpty()
        languageRadioMap[localeLanguage]?.let { radioId ->
            findViewById<RadioButton>(radioId).isChecked = true
        }
    }

    private fun onClickApply() {
        val themeNumber = if (vSwitchTheme.isChecked) 1 else 0
        val localeLanguage = languageRadioMap.entries.find {
            findViewById<RadioButton>(it.value).isChecked
        }?.key.orEmpty()

        val intent = Intent().apply {
            putExtra(ConstValue.THEME_NUMBER, themeNumber)
            putExtra(ConstValue.LOCALE_LANGUAGE, localeLanguage)
        }
        setResult(Activity.RESULT_OK, intent)
        finish()
    }

    private fun onClickCancel() {
        setResult(Activity.RESULT_CANCELED)
        finish()
    }

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

    // 言語設定
    override fun attachBaseContext(base: Context) {
        val pref = base.getSharedPreferences(ConstValue.SETTINGS, Context.MODE_PRIVATE)
        val localeLanguage = pref.getString(ConstValue.LOCALE_LANGUAGE, "").orEmpty()
        val isValidLocale = localeLanguage.isNotEmpty() && Locale.getAvailableLocales().any { it.language == localeLanguage }
        if (isValidLocale) {
            val locale = Locale(localeLanguage)
            val config = Configuration(base.resources.configuration)
            val localeList = LocaleList(locale)
            LocaleList.setDefault(localeList)
            config.setLocales(localeList)
            super.attachBaseContext(base.createConfigurationContext(config))
        } else {
            super.attachBaseContext(base)
        }
    }

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

}

app/src/main/java/jp/aosystem/cidr/ConstValue.kt

package jp.aosystem.cidr

object ConstValue {
    internal const val AD_UNIT_ID: String = "ca-app-pub-0000000000000000/0000000000"
    internal const val SETTINGS: String = "settings"
    internal const val LOCALE_LANGUAGE: String = "localeLanguage"
    internal const val THEME_NUMBER: String = "themeNumber"
}

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:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/back13"
        android:focusable="true"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

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

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:clickable="true"
                android:focusable="true"
                android:focusableInTouchMode="true"
                android:orientation="vertical">


                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="48dp"
                        android:layout_weight="5"
                        android:background="@color/back2"
                        android:gravity="center"
                        android:text="@string/title" />

                    <TextView
                        android:id="@+id/textSetting"
                        android:layout_width="wrap_content"
                        android:layout_height="48dp"
                        android:layout_weight="1"
                        android:background="@color/back1"
                        android:gravity="center"
                        android:text="@string/setting" />
                </LinearLayout>


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

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:background="@color/back3"
                        android:orientation="horizontal"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginEnd="10dp"
                            android:text="@string/input_ipaddr" />

                        <EditText
                            android:id="@+id/editTextIPAddress"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:digits="0123456789."
                            android:ems="10"
                            android:hint="0.0.0.0"
                            android:inputType="numberDecimal" />

                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:background="@color/back4"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/input_subnetmask" />

                        <Spinner
                            android:id="@+id/spinner1"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:gravity="start" />
                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/back5"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/label0" />

                        <TextView
                            android:id="@+id/textResult0"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="0.0.0.0"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />
                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/back6"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/label1" />

                        <TextView
                            android:id="@+id/textResult1"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="0.0.0.0 ~ 0.0.0.0"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />
                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/back7"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/label2" />

                        <TextView
                            android:id="@+id/textResult2"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="0.0.0.0"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />
                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/back8"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/label3" />

                        <TextView
                            android:id="@+id/textResult3"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="0.0.0.0 (single)"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />
                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/back9"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/label4" />

                        <TextView
                            android:id="@+id/textResult4"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="0.0.0.0"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />
                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/back10"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/label5" />

                        <TextView
                            android:id="@+id/textResult5"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="0.0.0.0/32"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />
                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/back11"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/label6" />

                        <TextView
                            android:id="@+id/textResult6"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="255.255.255.255"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />
                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@color/back12"
                        android:orientation="vertical"
                        android:paddingStart="20dp"
                        android:paddingTop="10dp"
                        android:paddingEnd="20dp"
                        android:paddingBottom="10dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/label7" />

                        <TextView
                            android:id="@+id/textResult7"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="5dp"
                            android:text="00000000.00000000.00000000.00000000"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />

                        <TextView
                            android:id="@+id/textResult8"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="3dp"
                            android:text="11111111.11111111.11111111.11111111"
                            android:textColor="?android:attr/textColorPrimary"
                            android:textStyle="bold" />
                    </LinearLayout>

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

                </LinearLayout>
            </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"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="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: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="6"
            android:background="@color/back1"
            android:gravity="center"
            android:minHeight="48dip"
            android:onClick="onClickCancel"
            android:text="@android:string/cancel" />

        <TextView
            android:id="@+id/textApply"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="6"
            android:background="@color/back2"
            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/switchTheme"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/darkTheme" />

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

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

            <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/system" />

                <RadioButton
                    android:id="@+id/radioLanguageEn"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/english" />

                <RadioButton
                    android:id="@+id/radioLanguageJa"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/japanese" />
            </RadioGroup>

            <View
                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="150dp" />
        </LinearLayout>
    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>