Compare commits

..

6 Commits

Author SHA1 Message Date
99d309adc1
Merge pull request #60 from b13st/fix/hce-send-crash
Fix double character deletion causing crash on HCE transfer to VitalWear
2026-07-01 17:24:49 +02:00
2760af5d2b
Merge pull request #59 from b13st/chore/visual-improvements
improving various visuals
2026-07-01 17:23:34 +02:00
b13st
931f730406 Fix double character deletion causing crash on HCE transfer to VitalWear
Character was deleted from the local DB both right after sendCharacterToWatch
and again in WritingScreen's completion callback. The second deletion failed
because the character no longer existed, causing the reported random crash
when sending back to the watch. Deletion is now handled only once, in
WritingScreen.
2026-07-01 15:04:26 +02:00
b13st
4eaf6cdf1b Fix double character deletion causing crash on HCE transfer to VitalWear
Character was deleted from the local DB both right after sendCharacterToWatch
and again in WritingScreen's completion callback. The second deletion failed
because the character no longer existed, causing the reported random crash
when sending back to the watch. Deletion is now handled only once, in
WritingScreen.
2026-07-01 15:00:56 +02:00
b13st
416b30f7a8 improving various visuals 2026-07-01 13:51:34 +02:00
df713855f5 I forgot to update the version number. 2026-06-29 21:26:11 +02:00
9 changed files with 25 additions and 27 deletions

View File

@ -16,7 +16,7 @@ android {
minSdk = 28 minSdk = 28
targetSdk = 37 targetSdk = 37
versionCode = 1 versionCode = 1
versionName = "Alpha 0.6.4" versionName = "Alpha 0.6.5"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }

View File

@ -2124,8 +2124,8 @@ fun BattlesScreen() {
// Create APIBattleCharacter from database character // Create APIBattleCharacter from database character
val playerCharacter = APIBattleCharacter( val playerCharacter = APIBattleCharacter(
name = "Player Digimon", // We could get this from the database if needed name = "Player Character", // We could get this from the database if needed
namekey = "player_digimon", // Name key for the character namekey = "player_digimon", // Name key for the character (functional lookup key, not shown)
charaId = formattedCardId, // Use the formatted card ID for sprite loading charaId = formattedCardId, // Use the formatted card ID for sprite loading
stage = characterData.stage, stage = characterData.stage,
attribute = characterData.attribute.ordinal, // Convert enum to int attribute = characterData.attribute.ordinal, // Convert enum to int
@ -2232,10 +2232,10 @@ fun BattlesScreen() {
) { ) {
// Show active character info // Show active character info
activeUserCharacter?.let { character -> activeUserCharacter?.let { character ->
Text("Active Digimon:") Text("Active character:")
Text("Stage: ${character.stage}") Text("Stage: ${character.stage}")
activeCardId?.let { cardId -> activeCardId?.let { cardId ->
Text("Digimon ID: $cardId", fontSize = 14.sp, color = Color.Blue, fontWeight = FontWeight.Bold) Text("Character ID: $cardId", fontSize = 14.sp, color = Color.Blue, fontWeight = FontWeight.Bold)
} }
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
@ -2336,7 +2336,7 @@ fun BattlesScreen() {
textAlign = TextAlign.Center) textAlign = TextAlign.Center)
} }
} else { } else {
Text("Your Digimon must be at least Stage 2 to battle", Text("Your character must be at least Stage 2 to battle",
fontSize = 16.sp, fontSize = 16.sp,
color = Color.Red, color = Color.Red,
textAlign = TextAlign.Center) textAlign = TextAlign.Center)

View File

@ -43,7 +43,7 @@ fun ChooseConnectOption(
.padding(contentPadding) .padding(contentPadding)
) { ) {
Text( Text(
text = "Bandai Toys = Vital Bracelet, Vital Hero, BE Bracelet", text = "VB, VH, VBBE",
fontSize = 14.sp, fontSize = 14.sp,
modifier = Modifier.padding(bottom = 24.dp) modifier = Modifier.padding(bottom = 24.dp)
) )

View File

@ -231,9 +231,7 @@ class ScanScreenControllerImpl(
val proto = VitalWearCharacterExporter(componentActivity, database).buildCharacterProto(characterId) val proto = VitalWearCharacterExporter(componentActivity, database).buildCharacterProto(characterId)
val client = VitalWearHceReaderClient(isoDep) val client = VitalWearHceReaderClient(isoDep)
client.sendCharacterToWatch(proto) client.sendCharacterToWatch(proto)
database.userCharacterDao().deleteCharacterById(characterId) Log.i("NFC_WRITE", "Character sent to VitalWear (id=$characterId), deletion deferred to WritingScreen")
pendingExportCharacterId = null
Log.i("NFC_WRITE", "Character sent to VitalWear and deleted from app (id=$characterId)")
componentActivity.runOnUiThread { componentActivity.runOnUiThread {
Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_sent_character_success), Toast.LENGTH_SHORT).show() Toast.makeText(componentActivity, componentActivity.getString(R.string.scan_sent_character_success), Toast.LENGTH_SHORT).show()
} }

View File

@ -104,7 +104,7 @@ fun TransferAnimationScreen(
) { ) {
Image( Image(
bitmap = preview.imageBitmap, bitmap = preview.imageBitmap,
contentDescription = "Transferred Digimon sprite", contentDescription = "Transferred character sprite",
modifier = Modifier modifier = Modifier
.size(preview.dpWidth, preview.dpHeight) .size(preview.dpWidth, preview.dpHeight)
.padding(8.dp), .padding(8.dp),

View File

@ -136,7 +136,7 @@ class SettingsScreenControllerImpl(
secrets = secretsImporter.importSecrets(it) secrets = secretsImporter.importSecrets(it)
} catch (e: Exception) { } catch (e: Exception) {
context.runOnUiThread { context.runOnUiThread {
Toast.makeText(context, "Secrets import failed. Please only select the official Vital Arena App 2.1.0 APK.", Toast.LENGTH_SHORT).show() Toast.makeText(context, "Secrets import failed. Please only select the official app APK.", Toast.LENGTH_SHORT).show()
} }
return@launch return@launch
} }

View File

@ -24,7 +24,7 @@
<string name="scan_sent_dim_success">DIMの転送に成功しました。</string> <string name="scan_sent_dim_success">DIMの転送に成功しました。</string>
<string name="scan_nfc_must_be_enabled">NFC機能を有効にして下さい。</string> <string name="scan_nfc_must_be_enabled">NFC機能を有効にして下さい。</string>
<string name="settings_title">設定</string> <string name="settings_title">設定</string>
<string name="scan_missing_secrets">Vital ArenaのAPKを読み込みして下さい。</string> <string name="scan_missing_secrets">公式アプリのAPKを読み込みして下さい。</string>
<string name="scan_sent_character_success">転送が成功しました。</string> <string name="scan_sent_character_success">転送が成功しました。</string>
<string name="scan_error_generic">エラー</string> <string name="scan_error_generic">エラー</string>
<string name="settings_about_desc">このアプリについて</string> <string name="settings_about_desc">このアプリについて</string>
@ -64,7 +64,7 @@
<string name="settings_section_dim_bem">DiM / BEm管理</string> <string name="settings_section_dim_bem">DiM / BEm管理</string>
<string name="settings_section_data">データ管理</string> <string name="settings_section_data">データ管理</string>
<string name="settings_import_apk_title">アプリのインポート</string> <string name="settings_import_apk_title">アプリのインポート</string>
<string name="settings_import_apk_desc">Vital Arena 2.1.0のAPKファイルを読み込みします。</string> <string name="settings_import_apk_desc">公式アプリのAPKファイルを読み込みします。</string>
<string name="settings_import_card_title">カードのインポート</string> <string name="settings_import_card_title">カードのインポート</string>
<string name="settings_section_about">概要 / クレジット</string> <string name="settings_section_about">概要 / クレジット</string>
<string name="dex_chara_fusions_button">ジョグレス</string> <string name="dex_chara_fusions_button">ジョグレス</string>

View File

@ -43,13 +43,13 @@
Os segredos ainda não foram importados. Vá em Configurações e importe o APK. Os segredos ainda não foram importados. Vá em Configurações e importe o APK.
</string> </string>
<string name="scan_title">Escanear um Vital Bracelet</string> <string name="scan_title">Escanear um VB</string>
<string name="scan_vb_to_app">Vital Bracelet para o app</string> <string name="scan_vb_to_app">VB para o app</string>
<string name="scan_app_to_vb">App para o Vital Bracelet</string> <string name="scan_app_to_vb">App para o VB</string>
<string name="scan_no_nfc_on_device">O dispositivo não possui NFC!</string> <string name="scan_no_nfc_on_device">O dispositivo não possui NFC!</string>
<string name="scan_tag_not_vb">A tag detectada não é do Vital Bracelet.</string> <string name="scan_tag_not_vb">A tag detectada não é do VB.</string>
<string name="scan_missing_secrets">" Segredos ausentes. Vá em Configurações e importe o APK do Vital Arena. "</string> <string name="scan_missing_secrets">" Segredos ausentes. Vá em Configurações e importe o APK do app oficial. "</string>
<string name="scan_sent_character_success">Personagem enviado com sucesso!</string> <string name="scan_sent_character_success">Personagem enviado com sucesso!</string>
<string name="scan_error_generic">Ops!</string> <string name="scan_error_generic">Ops!</string>
<string name="scan_sent_dim_success">DIM enviado com sucesso!</string> <string name="scan_sent_dim_success">DIM enviado com sucesso!</string>
@ -64,7 +64,7 @@
<string name="settings_import_apk_title">Importar APK</string> <string name="settings_import_apk_title">Importar APK</string>
<string name="settings_import_apk_desc"> <string name="settings_import_apk_desc">
Importar segredos do APK do Vital Arena 2.1.0 Importar segredos do APK do app oficial
</string> </string>
<string name="settings_import_card_title">Importar card</string> <string name="settings_import_card_title">Importar card</string>
@ -106,7 +106,7 @@
Responsável pelo design do ícone do aplicativo em SVG. Responsável pelo design do ícone do aplicativo em SVG.
</string> </string>
<string name="action_place_near_reader">Aproxime o seu Vital Bracelet do leitor...</string> <string name="action_place_near_reader">Aproxime o seu VB do leitor...</string>
<string name="action_cancel">Cancelar</string> <string name="action_cancel">Cancelar</string>
<string name="read_character_title">Ler personagem</string> <string name="read_character_title">Ler personagem</string>

View File

@ -43,13 +43,13 @@
Secrets not yet imported. Go to Settings and Import APK. Secrets not yet imported. Go to Settings and Import APK.
</string> </string>
<string name="scan_title">Scan a Vital Bracelet</string> <string name="scan_title">Scan a VB</string>
<string name="scan_vb_to_app">Watch to VBH</string> <string name="scan_vb_to_app">Watch to VBH</string>
<string name="scan_app_to_vb">VBH to Watch</string> <string name="scan_app_to_vb">VBH to Watch</string>
<string name="scan_no_nfc_on_device">No NFC on device!</string> <string name="scan_no_nfc_on_device">No NFC on device!</string>
<string name="scan_tag_not_vb">Tag detected is not VB</string> <string name="scan_tag_not_vb">Tag detected is not VB</string>
<string name="scan_missing_secrets">" Missing Secrets. Go to settings and import Vital Arena APK. "</string> <string name="scan_missing_secrets">" Missing Secrets. Go to settings and import the official app APK. "</string>
<string name="scan_sent_character_success">Sent character successfully!</string> <string name="scan_sent_character_success">Sent character successfully!</string>
<string name="scan_error_generic">Whoops</string> <string name="scan_error_generic">Whoops</string>
<string name="scan_sent_dim_success">Sent DIM successfully!</string> <string name="scan_sent_dim_success">Sent DIM successfully!</string>
@ -65,7 +65,7 @@
<string name="settings_import_apk_title">Import APK</string> <string name="settings_import_apk_title">Import APK</string>
<string name="settings_import_apk_desc"> <string name="settings_import_apk_desc">
Import Secrets From Vital Arena APK Import Secrets From the official app APK
</string> </string>
<string name="settings_import_card_title">Import card</string> <string name="settings_import_card_title">Import card</string>
@ -109,7 +109,7 @@
<string name="credits_RedEyez_description"> <string name="credits_RedEyez_description">
Devout Debugger. Devout Debugger.
</string> </string>
<string name="action_place_near_reader">Place your Vital Bracelet near the reader...</string> <string name="action_place_near_reader">Place your VB near the reader...</string>
<string name="action_cancel">Cancel</string> <string name="action_cancel">Cancel</string>
<string name="read_character_title">Read character</string> <string name="read_character_title">Read character</string>
@ -220,10 +220,10 @@
<string name="home_special_mission_delete_remove">Remove</string> <string name="home_special_mission_delete_remove">Remove</string>
<string name="settings_companion_import_card_image_title">Import Card Image</string> <string name="settings_companion_import_card_image_title">Import Card Image</string>
<string name="companion_validation_connect_vb">Connect Vital Bracelet</string> <string name="companion_validation_connect_vb">Connect VB</string>
<string name="companion_card_import_success">Card imported successfully!</string> <string name="companion_card_import_success">Card imported successfully!</string>
<string name="companion_firmware_no_watch">No watch found!</string> <string name="companion_firmware_no_watch">No watch found!</string>
<string name="companion_validation_insert_card">Insert card into Vital Bracelet</string> <string name="companion_validation_insert_card">Insert card into VB</string>
<string name="companion_validation_success">Validation successful!</string> <string name="companion_validation_success">Validation successful!</string>
<string name="companion_loading_select_firmware">Select firmware file</string> <string name="companion_loading_select_firmware">Select firmware file</string>
<string name="companion_firmware_sent_success">Firmware sent successfully!</string> <string name="companion_firmware_sent_success">Firmware sent successfully!</string>