M app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt => app/src/main/java/com/github/nacabaro/vbhelper/MainActivity.kt +4 -10
@@ 25,9 25,7 @@ import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData
import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter
import com.github.nacabaro.vbhelper.navigation.AppNavigationHandlers
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenControllerImpl
-import com.github.nacabaro.vbhelper.screens.settingsScreen.NewSettingsScreenControllerImpl
-import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenController
-import com.github.nacabaro.vbhelper.source.ApkSecretsImporter
+import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
import com.github.nacabaro.vbhelper.ui.theme.VBHelperTheme
import com.github.nacabaro.vbhelper.utils.DeviceType
import kotlinx.coroutines.flow.MutableStateFlow
@@ 57,8 55,6 @@ class MainActivity : ComponentActivity() {
registerFileActivityResult()
val application = applicationContext as VBHelper
- val settingsScreenController = SettingsScreenController.Factory(this, ApkSecretsImporter(), application.container.dataStoreSecretsRepository)
- .buildSettingScreenHandlers()
val scanScreenController = ScanScreenControllerImpl(
application.container.dataStoreSecretsRepository.secretsFlow,
this::handleReceivedNfcCharacter,
@@ 66,13 62,13 @@ class MainActivity : ComponentActivity() {
this::registerActivityLifecycleListener,
this::unregisterActivityLifecycleListener
)
- val newSettingsScreenController = NewSettingsScreenControllerImpl(this)
+ val settingsScreenController = SettingsScreenControllerImpl(this)
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
VBHelperTheme {
- MainApplication(settingsScreenController, scanScreenController, newSettingsScreenController)
+ MainApplication(scanScreenController, settingsScreenController)
}
}
Log.i("MainActivity", "Activity onCreated")
@@ 192,16 188,14 @@ class MainActivity : ComponentActivity() {
@Composable
private fun MainApplication(
- settingsScreenController: SettingsScreenController,
scanScreenController: ScanScreenControllerImpl,
- newSettingsScreenController: NewSettingsScreenControllerImpl
+ settingsScreenController: SettingsScreenControllerImpl
) {
AppNavigation(
applicationNavigationHandlers = AppNavigationHandlers(
settingsScreenController,
scanScreenController,
- newSettingsScreenController
),
onClickImportCard = {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
M app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt => app/src/main/java/com/github/nacabaro/vbhelper/navigation/AppNavigation.kt +2 -5
@@ 15,15 15,13 @@ import com.github.nacabaro.vbhelper.screens.ItemsScreen
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreen
import com.github.nacabaro.vbhelper.screens.scanScreen.ScanScreenControllerImpl
import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreen
-import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenController
import com.github.nacabaro.vbhelper.screens.SpriteViewer
import com.github.nacabaro.vbhelper.screens.StorageScreen
-import com.github.nacabaro.vbhelper.screens.settingsScreen.NewSettingsScreenControllerImpl
+import com.github.nacabaro.vbhelper.screens.settingsScreen.SettingsScreenControllerImpl
data class AppNavigationHandlers(
- val settingsScreenController: SettingsScreenController,
+ val settingsScreenController: SettingsScreenControllerImpl,
val scanScreenController: ScanScreenControllerImpl,
- val newSettingsScreenController: NewSettingsScreenControllerImpl
)
@Composable
@@ 76,7 74,6 @@ fun AppNavigation(
SettingsScreen(
navController = navController,
settingsScreenController = applicationNavigationHandlers.settingsScreenController,
- newSettingsScreenController = applicationNavigationHandlers.newSettingsScreenController,
onClickImportCard = onClickImportCard,
)
}
D app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/NewSettingsScreenController.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/NewSettingsScreenController.kt +0 -8
@@ 1,8 0,0 @@
-package com.github.nacabaro.vbhelper.screens.settingsScreen
-
-import android.net.Uri
-
-interface NewSettingsScreenController {
- fun onClickOpenDirectory()
- fun onClickImportDatabase()
-}>
\ No newline at end of file
M app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreen.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreen.kt +4 -17
@@ 1,9 1,5 @@
package com.github.nacabaro.vbhelper.screens.settingsScreen
-import android.net.Uri
-import androidx.activity.ComponentActivity
-import androidx.activity.result.ActivityResultLauncher
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ 22,14 18,11 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.github.nacabaro.vbhelper.components.TopBanner
-import com.github.nacabaro.vbhelper.navigation.AppNavigation
-import com.github.nacabaro.vbhelper.navigation.NavigationItems
@Composable
fun SettingsScreen(
navController: NavController,
- settingsScreenController: SettingsScreenController,
- newSettingsScreenController: NewSettingsScreenControllerImpl,
+ settingsScreenController: SettingsScreenControllerImpl,
onClickImportCard: () -> Unit
) {
Scaffold (
@@ 52,14 45,14 @@ fun SettingsScreen(
) {
SettingsSection("NFC Communication")
SettingsEntry(title = "Import APK", description = "Import Secrets From Vital Arean 2.1.0 APK") {
- settingsScreenController.apkFilePickLauncher.launch(arrayOf("*/*"))
+ settingsScreenController.onClickImportApk()
}
SettingsSection("Data management")
SettingsEntry(title = "Export data", description = "Export application database") {
- newSettingsScreenController.onClickOpenDirectory()
+ settingsScreenController.onClickOpenDirectory()
}
SettingsEntry(title = "Import data", description = "Import application database") {
- newSettingsScreenController.onClickImportDatabase()
+ settingsScreenController.onClickImportDatabase()
}
SettingsSection("DiM/BEm management")
SettingsEntry(title = "Import DiM card", description = "Import DiM/BEm card file", onClick = onClickImportCard)
@@ 71,12 64,6 @@ fun SettingsScreen(
}
}
-fun buildFilePickLauncher(activity: ComponentActivity, onItemPicked: (Uri?) -> Unit): ActivityResultLauncher<Array<String>> {
- return activity.registerForActivityResult(ActivityResultContracts.OpenDocument()) {
- onItemPicked.invoke(it)
- }
-}
-
@Composable
fun SettingsEntry(
title: String,
D app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenController.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenController.kt +0 -71
@@ 1,71 0,0 @@
-package com.github.nacabaro.vbhelper.screens.settingsScreen
-
-import android.net.Uri
-import android.widget.Toast
-import androidx.activity.ComponentActivity
-import androidx.activity.result.ActivityResultLauncher
-import androidx.activity.result.contract.ActivityResultContracts
-import androidx.lifecycle.lifecycleScope
-import com.github.nacabaro.vbhelper.source.SecretsImporter
-import com.github.nacabaro.vbhelper.source.SecretsRepository
-import com.github.nacabaro.vbhelper.source.proto.Secrets
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-
-data class SettingsScreenController(val apkFilePickLauncher: ActivityResultLauncher<Array<String>>) {
-
- class Factory(private val componentActivity: ComponentActivity, private val secretsImporter: SecretsImporter, private val secretsRepository: SecretsRepository) {
-
- fun buildSettingScreenHandlers(): SettingsScreenController {
- return SettingsScreenController(
- apkFilePickLauncher = buildFilePickerActivityLauncher(this::importApk)
- )
- }
-
- private fun buildFilePickerActivityLauncher(onResult : (Uri?) ->Unit): ActivityResultLauncher<Array<String>> {
- return componentActivity.registerForActivityResult(ActivityResultContracts.OpenDocument()) {
- onResult.invoke(it)
- }
- }
-
- private fun importApk(uri: Uri?) {
- if(uri == null) {
- componentActivity.runOnUiThread {
- Toast.makeText(componentActivity, "APK Import Cancelled", Toast.LENGTH_SHORT)
- .show()
- }
- return
- }
- componentActivity.lifecycleScope.launch(Dispatchers.IO) {
- componentActivity.contentResolver.openInputStream(uri).use {
- if(it == null) {
- componentActivity.runOnUiThread {
- Toast.makeText(
- componentActivity,
- "Selected file is empty!",
- Toast.LENGTH_SHORT
- ).show()
- }
- return@launch
- }
- var secrets: Secrets? = null
- try {
- secrets = secretsImporter.importSecrets(it)
- } catch (e: Exception) {
- componentActivity.runOnUiThread {
- Toast.makeText(componentActivity, "Secrets import failed. Please only select the official Vital Arena App 2.1.0 APK.", Toast.LENGTH_SHORT).show()
- }
- return@launch
- }
- componentActivity.lifecycleScope.launch(Dispatchers.IO) {
- secretsRepository.updateSecrets(secrets)
- }.invokeOnCompletion {
- componentActivity.runOnUiThread {
- Toast.makeText(componentActivity, "Secrets successfully imported. Connections with devices are now possible.", Toast.LENGTH_SHORT).show()
- }
- }
- }
- }
- }
- }
-}>
\ No newline at end of file
R app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/NewSettingsScreenControllerImpl.kt => app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt +64 -9
@@ 10,24 10,33 @@ import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.github.nacabaro.vbhelper.di.VBHelper
+import com.github.nacabaro.vbhelper.source.ApkSecretsImporter
+import com.github.nacabaro.vbhelper.source.SecretsImporter
+import com.github.nacabaro.vbhelper.source.SecretsRepository
+import com.github.nacabaro.vbhelper.source.proto.Secrets
import kotlinx.coroutines.Dispatchers
import java.io.File
import java.io.InputStream
import java.io.OutputStream
-class NewSettingsScreenControllerImpl(
+class SettingsScreenControllerImpl(
private val context: ComponentActivity,
-): NewSettingsScreenController {
+): SettingsScreenController {
+ private val roomDbName = "internalDb"
private val filePickerLauncher: ActivityResultLauncher<String>
private val filePickerOpenerLauncher: ActivityResultLauncher<Array<String>>
+ private val filePickerApk: ActivityResultLauncher<Array<String>>
+ private val secretsImporter: SecretsImporter = ApkSecretsImporter()
+ private val application = context.applicationContext as VBHelper
+ private val secretsRepository: SecretsRepository = application.container.dataStoreSecretsRepository
init {
filePickerLauncher = context.registerForActivityResult(
ActivityResultContracts.CreateDocument("application/octet-stream")
) { uri ->
if (uri != null) {
- exportDatabase("internalDb", uri)
+ exportDatabase(uri)
} else {
context.runOnUiThread {
Toast.makeText(context, "No destination selected", Toast.LENGTH_SHORT)
@@ 40,13 49,25 @@ class NewSettingsScreenControllerImpl(
ActivityResultContracts.OpenDocument()
) { uri ->
if (uri != null) {
- importDatabase("internalDb", uri)
+ importDatabase(uri)
} else {
context.runOnUiThread {
Toast.makeText(context, "No source selected", Toast.LENGTH_SHORT).show()
}
}
}
+
+ filePickerApk = context.registerForActivityResult(
+ ActivityResultContracts.OpenDocument()
+ ) { uri ->
+ if (uri != null) {
+ importApk(uri)
+ } else {
+ context.runOnUiThread {
+ Toast.makeText(context, "APK import cancelled", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
}
override fun onClickOpenDirectory() {
@@ 57,10 78,13 @@ class NewSettingsScreenControllerImpl(
filePickerOpenerLauncher.launch(arrayOf("application/octet-stream"))
}
- private fun exportDatabase(roomDbName: String, destinationUri: Uri) {
+ override fun onClickImportApk() {
+ filePickerApk.launch(arrayOf("*/*"))
+ }
+
+ private fun exportDatabase(destinationUri: Uri) {
context.lifecycleScope.launch(Dispatchers.IO) {
try {
- val application = context.applicationContext as VBHelper
val dbFile = File(context.getDatabasePath(roomDbName).absolutePath)
if (!dbFile.exists()) {
throw IllegalStateException("Database file does not exist!")
@@ 88,11 112,9 @@ class NewSettingsScreenControllerImpl(
}
}
- private fun importDatabase(roomDbName: String, sourceUri: Uri) {
+ private fun importDatabase(sourceUri: Uri) {
context.lifecycleScope.launch(Dispatchers.IO) {
try {
- var application = context.applicationContext as VBHelper
-
if (!getFileNameFromUri(sourceUri)!!.endsWith(".vbhelper")) {
context.runOnUiThread {
Toast.makeText(context, "Invalid file format", Toast.LENGTH_SHORT).show()
@@ 153,4 175,37 @@ class NewSettingsScreenControllerImpl(
}
outputStream.flush()
}
+
+ private fun importApk(uri: Uri) {
+ context.lifecycleScope.launch(Dispatchers.IO) {
+ context.contentResolver.openInputStream(uri).use {
+ if(it == null) {
+ context.runOnUiThread {
+ Toast.makeText(
+ context,
+ "Selected file is empty!",
+ Toast.LENGTH_SHORT
+ ).show()
+ }
+ return@launch
+ }
+ val secrets: Secrets?
+ try {
+ secrets = secretsImporter.importSecrets(it)
+ } catch (e: Exception) {
+ context.runOnUiThread {
+ Toast.makeText(context, "Secrets import failed. Please only select the official Vital Arena App 2.1.0 APK.", Toast.LENGTH_SHORT).show()
+ }
+ return@launch
+ }
+ context.lifecycleScope.launch(Dispatchers.IO) {
+ secretsRepository.updateSecrets(secrets)
+ }.invokeOnCompletion {
+ context.runOnUiThread {
+ Toast.makeText(context, "Secrets successfully imported. Connections with devices are now possible.", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+ }
}=
\ No newline at end of file