mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-20 05:23:12 -07:00
Prepare Importing Settings on Android
This commit is contained in:
parent
e3ea1e40b2
commit
2aa297d203
3 changed files with 85 additions and 10 deletions
|
@ -42,11 +42,11 @@ class MacAddress(v: Long)
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor(string: String) : this(
|
constructor(string: String) : this(
|
||||||
(Regex("([0-9A-Fa-f]{2})[:-]{5}([0-9A-Fa-f]{2})").matchEntire(string)
|
(Regex("([0-9A-Fa-f]{2})[:-]([0-9A-Fa-f]{2})[:-]([0-9A-Fa-f]{2})[:-]([0-9A-Fa-f]{2})[:-]([0-9A-Fa-f]{2})[:-]([0-9A-Fa-f]{2})").matchEntire(string)
|
||||||
?: throw IllegalArgumentException("Invalid MAC Address String"))
|
?: throw IllegalArgumentException("Invalid MAC Address String"))
|
||||||
.groupValues
|
.groupValues
|
||||||
.subList(1, 7)
|
.subList(1, 7)
|
||||||
.map { it.toByte() }
|
.map { it.toUByte(16).toByte() }
|
||||||
.toByteArray())
|
.toByteArray())
|
||||||
|
|
||||||
val value: Long = v and 0xffffffffffff
|
val value: Long = v and 0xffffffffffff
|
||||||
|
|
|
@ -20,7 +20,9 @@ package com.metallic.chiaki.common
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
|
import android.util.Log
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import com.metallic.chiaki.R
|
import com.metallic.chiaki.R
|
||||||
import com.squareup.moshi.*
|
import com.squareup.moshi.*
|
||||||
|
@ -29,7 +31,9 @@ import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.rxkotlin.Singles
|
import io.reactivex.rxkotlin.Singles
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
|
import okio.Okio
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
class SerializedRegisteredHost(
|
class SerializedRegisteredHost(
|
||||||
|
@ -100,10 +104,14 @@ private fun moshi() =
|
||||||
.add(ByteArrayJsonAdapter())
|
.add(ByteArrayJsonAdapter())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
private fun Moshi.serializedSettingsAdapter() =
|
||||||
|
adapter(SerializedSettings::class.java)
|
||||||
|
.serializeNulls()
|
||||||
|
|
||||||
private const val KEY_FORMAT = "format"
|
private const val KEY_FORMAT = "format"
|
||||||
private const val FORMAT = "chiaki-settings"
|
private const val FORMAT = "chiaki-settings"
|
||||||
private const val KEY_VERSION = "version"
|
private const val KEY_VERSION = "version"
|
||||||
private const val VERSION = "1"
|
private const val VERSION = 1
|
||||||
private const val KEY_SETTINGS = "settings"
|
private const val KEY_SETTINGS = "settings"
|
||||||
|
|
||||||
fun exportAllSettings(db: AppDatabase) = SerializedSettings.fromDatabase(db)
|
fun exportAllSettings(db: AppDatabase) = SerializedSettings.fromDatabase(db)
|
||||||
|
@ -111,9 +119,7 @@ fun exportAllSettings(db: AppDatabase) = SerializedSettings.fromDatabase(db)
|
||||||
.map {
|
.map {
|
||||||
val buffer = Buffer()
|
val buffer = Buffer()
|
||||||
val writer = JsonWriter.of(buffer)
|
val writer = JsonWriter.of(buffer)
|
||||||
val adapter = moshi()
|
val adapter = moshi().serializedSettingsAdapter()
|
||||||
.adapter(SerializedSettings::class.java)
|
|
||||||
.serializeNulls()
|
|
||||||
writer.indent = " "
|
writer.indent = " "
|
||||||
writer.
|
writer.
|
||||||
beginObject()
|
beginObject()
|
||||||
|
@ -125,8 +131,9 @@ fun exportAllSettings(db: AppDatabase) = SerializedSettings.fromDatabase(db)
|
||||||
buffer.readUtf8()
|
buffer.readUtf8()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exportAndShareAllSettings(db: AppDatabase, activity: Activity): Disposable
|
fun exportAndShareAllSettings(activity: Activity): Disposable
|
||||||
{
|
{
|
||||||
|
val db = getDatabase(activity)
|
||||||
val dir = File(activity.cacheDir, "export_settings")
|
val dir = File(activity.cacheDir, "export_settings")
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
val file = File(dir, "chiaki-settings.json")
|
val file = File(dir, "chiaki-settings.json")
|
||||||
|
@ -147,3 +154,52 @@ fun exportAndShareAllSettings(db: AppDatabase, activity: Activity): Disposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun importSettingsFromUri(activity: Activity, uri: Uri)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
val inputStream = activity.contentResolver.openInputStream(uri) ?: throw IOException()
|
||||||
|
val buffer = Okio.buffer(Okio.source(inputStream))
|
||||||
|
val reader = JsonReader.of(buffer)
|
||||||
|
val adapter = moshi().serializedSettingsAdapter()
|
||||||
|
|
||||||
|
var format: String? = null
|
||||||
|
var version: Int? = null
|
||||||
|
var settingsValue: Any? = null
|
||||||
|
|
||||||
|
reader.beginObject()
|
||||||
|
while(reader.hasNext())
|
||||||
|
{
|
||||||
|
when(reader.nextName())
|
||||||
|
{
|
||||||
|
KEY_FORMAT -> format = reader.nextString()
|
||||||
|
KEY_VERSION -> version = reader.nextInt()
|
||||||
|
KEY_SETTINGS -> settingsValue = reader.readJsonValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.endObject()
|
||||||
|
|
||||||
|
if(format == null || version == null || settingsValue == null)
|
||||||
|
throw IOException("Missing format, version or settings from JSON")
|
||||||
|
if(format != FORMAT)
|
||||||
|
throw IOException("Value of format is invalid")
|
||||||
|
if(version != VERSION) // Add migrations here when necessary
|
||||||
|
throw IOException("Value of version is invalid")
|
||||||
|
|
||||||
|
val settings = adapter.fromJsonValue(settingsValue)
|
||||||
|
Log.i("SerializedSettings", "would import: $settings")
|
||||||
|
// TODO: show dialog and import
|
||||||
|
}
|
||||||
|
catch(e: IOException)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
catch(e: JsonDataException)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package com.metallic.chiaki.settings
|
package com.metallic.chiaki.settings
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
@ -83,7 +84,10 @@ class DataStore(val preferences: Preferences): PreferenceDataStore()
|
||||||
|
|
||||||
class SettingsFragment: PreferenceFragmentCompat(), TitleFragment
|
class SettingsFragment: PreferenceFragmentCompat(), TitleFragment
|
||||||
{
|
{
|
||||||
private lateinit var viewModel: SettingsViewModel
|
companion object
|
||||||
|
{
|
||||||
|
private const val PICK_SETTINGS_JSON_REQUEST = 1
|
||||||
|
}
|
||||||
|
|
||||||
private var disposable = CompositeDisposable()
|
private var disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
@ -91,7 +95,7 @@ class SettingsFragment: PreferenceFragmentCompat(), TitleFragment
|
||||||
{
|
{
|
||||||
val context = context ?: return
|
val context = context ?: return
|
||||||
|
|
||||||
viewModel = ViewModelProviders
|
val viewModel = ViewModelProviders
|
||||||
.of(this, viewModelFactory { SettingsViewModel(getDatabase(context), Preferences(context)) })
|
.of(this, viewModelFactory { SettingsViewModel(getDatabase(context), Preferences(context)) })
|
||||||
.get(SettingsViewModel::class.java)
|
.get(SettingsViewModel::class.java)
|
||||||
|
|
||||||
|
@ -146,11 +150,26 @@ class SettingsFragment: PreferenceFragmentCompat(), TitleFragment
|
||||||
{
|
{
|
||||||
val activity = activity ?: return
|
val activity = activity ?: return
|
||||||
disposable.clear()
|
disposable.clear()
|
||||||
exportAndShareAllSettings(viewModel.database, activity).addTo(disposable)
|
exportAndShareAllSettings(activity).addTo(disposable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun importSettings()
|
private fun importSettings()
|
||||||
{
|
{
|
||||||
|
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||||
|
addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
|
type = "application/json"
|
||||||
|
}
|
||||||
|
startActivityForResult(intent, PICK_SETTINGS_JSON_REQUEST)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
|
||||||
|
{
|
||||||
|
if(requestCode == PICK_SETTINGS_JSON_REQUEST && resultCode == Activity.RESULT_OK)
|
||||||
|
{
|
||||||
|
val activity = activity ?: return
|
||||||
|
data?.data?.also {
|
||||||
|
importSettingsFromUri(activity, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue