mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-06-05 13:52:54 +00:00
Swapped from using internal app storage to android device storage.
This commit is contained in:
parent
44c6382356
commit
b4d509aad9
@ -92,4 +92,11 @@ dependencies {
|
||||
implementation(libs.protobuf.javalite)
|
||||
implementation("androidx.compose.material:material")
|
||||
implementation("androidx.datastore:datastore-preferences:1.1.7")
|
||||
|
||||
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||
implementation("com.google.code.gson:gson:2.10.1")
|
||||
|
||||
// HTTP request logging
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
|
||||
}
|
||||
@ -7,6 +7,8 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
|
||||
tools:ignore="ScopedStorage" />
|
||||
|
||||
<application
|
||||
android:name=".di.VBHelper"
|
||||
|
||||
@ -32,9 +32,10 @@ class AttackSpriteManager(private val context: Context) {
|
||||
private val gson = Gson()
|
||||
private val characterDataCache = mutableMapOf<String, CharacterData>()
|
||||
|
||||
// Get the internal storage directory for attack sprites
|
||||
private fun getAttackTexturesPath(): String {
|
||||
return "battle_sprites/extracted_atksprites"
|
||||
// Get the external storage directory for attack sprites
|
||||
private fun getAttackTexturesBaseDir(): File {
|
||||
val externalDir = android.os.Environment.getExternalStorageDirectory()
|
||||
return File(externalDir, "VBHelper/battle_sprites/extracted_atksprites")
|
||||
}
|
||||
|
||||
fun getAttackSprite(characterId: String, isLarge: Boolean = false): Bitmap? {
|
||||
@ -58,9 +59,8 @@ class AttackSpriteManager(private val context: Context) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Load the attack sprite from internal storage
|
||||
val attackFilePath = "${getAttackTexturesPath()}/$attackFileName.png"
|
||||
val attackFile = File(context.filesDir, attackFilePath)
|
||||
// Load the attack sprite from external storage
|
||||
val attackFile = File(getAttackTexturesBaseDir(), "$attackFileName.png")
|
||||
println("AttackSpriteManager: Attack file path = ${attackFile.absolutePath}")
|
||||
println("AttackSpriteManager: Attack file exists = ${attackFile.exists()}")
|
||||
|
||||
@ -88,8 +88,9 @@ class AttackSpriteManager(private val context: Context) {
|
||||
}
|
||||
|
||||
try {
|
||||
// Load character data from JSON file in internal storage
|
||||
val characterDataFile = File(context.filesDir, "battle_sprites/extracted_digimon_stats/character_data/CharacterData.json")
|
||||
// Load character data from JSON file in external storage
|
||||
val externalDir = android.os.Environment.getExternalStorageDirectory()
|
||||
val characterDataFile = File(externalDir, "VBHelper/battle_sprites/extracted_digimon_stats/character_data/CharacterData.json")
|
||||
println("AttackSpriteManager: Character data file path = ${characterDataFile.absolutePath}")
|
||||
println("AttackSpriteManager: Character data file exists = ${characterDataFile.exists()}")
|
||||
|
||||
|
||||
@ -38,9 +38,10 @@ class BattleSpriteManager(private val context: Context) {
|
||||
private val gson = Gson()
|
||||
private val spriteCache = mutableMapOf<String, Bitmap>()
|
||||
|
||||
// Get the internal storage directory for sprite files
|
||||
// Get the external storage directory for sprite files
|
||||
private fun getSpriteBaseDir(): File {
|
||||
return File(context.filesDir, "battle_sprites/extracted_assets")
|
||||
val externalDir = android.os.Environment.getExternalStorageDirectory()
|
||||
return File(externalDir, "VBHelper/battle_sprites/extracted_assets")
|
||||
}
|
||||
|
||||
fun loadSprite(spriteName: String, atlasName: String): Bitmap? {
|
||||
|
||||
@ -10,9 +10,10 @@ import java.io.File
|
||||
class HitEffectSpriteManager(private val context: Context) {
|
||||
private val spriteCache = mutableMapOf<String, Bitmap>()
|
||||
|
||||
// Get the internal storage directory for hit effect sprites
|
||||
// Get the external storage directory for hit effect sprites
|
||||
private fun getHitSpritesDir(): File {
|
||||
return File(context.filesDir, "battle_sprites/extracted_hit_sprites")
|
||||
val externalDir = android.os.Environment.getExternalStorageDirectory()
|
||||
return File(externalDir, "VBHelper/battle_sprites/extracted_hit_sprites")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -9,9 +9,10 @@ import java.io.File
|
||||
class IndividualSpriteManager(private val context: Context) {
|
||||
private val spriteCache = mutableMapOf<String, Bitmap>()
|
||||
|
||||
// Get the internal storage directory for sprite files
|
||||
// Get the external storage directory for sprite files
|
||||
private fun getSpriteBaseDir(): File {
|
||||
return File(context.filesDir, "battle_sprites/extracted_assets/sprites")
|
||||
val externalDir = android.os.Environment.getExternalStorageDirectory()
|
||||
return File(externalDir, "VBHelper/battle_sprites/extracted_assets/sprites")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -9,7 +9,7 @@ import java.io.FileInputStream
|
||||
class SpriteFileManager(private val context: Context) {
|
||||
|
||||
// Get the external storage directory where files are already located
|
||||
private fun getExternalSpriteBaseDir(): File {
|
||||
fun getExternalSpriteBaseDir(): File {
|
||||
val externalDir = android.os.Environment.getExternalStorageDirectory()
|
||||
return File(externalDir, "VBHelper/battle_sprites")
|
||||
}
|
||||
@ -271,7 +271,7 @@ class SpriteFileManager(private val context: Context) {
|
||||
}
|
||||
|
||||
fun checkSpriteFilesExist(): Boolean {
|
||||
val battleSpritesDir = getInternalSpriteBaseDir()
|
||||
val battleSpritesDir = getExternalSpriteBaseDir()
|
||||
val extractedAssetsDir = File(battleSpritesDir, "extracted_assets")
|
||||
val extractedStatsDir = File(battleSpritesDir, "extracted_digimon_stats")
|
||||
val atkspritesDir = File(battleSpritesDir, "extracted_atksprites")
|
||||
@ -283,7 +283,7 @@ class SpriteFileManager(private val context: Context) {
|
||||
val atkspritesExist = atkspritesDir.exists() && atkspritesDir.listFiles()?.isNotEmpty() == true
|
||||
val battlebgsExist = battlebgsDir.exists() && battlebgsDir.listFiles()?.isNotEmpty() == true
|
||||
|
||||
println("Checking sprite files exist in internal storage:")
|
||||
println("Checking sprite files exist in external storage:")
|
||||
println(" battle_sprites exists: $battleSpritesExist")
|
||||
println(" extracted_assets exists: $assetsExist")
|
||||
println(" extracted_digimon_stats exists: $statsExist")
|
||||
|
||||
@ -34,6 +34,16 @@ import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.activity.ComponentActivity
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import kotlinx.coroutines.delay
|
||||
@ -1542,6 +1552,92 @@ fun EnemyBattleView(
|
||||
@Composable
|
||||
fun BattlesScreen() {
|
||||
val TAG = "BattleScreen"
|
||||
val context = LocalContext.current
|
||||
val activity = context as? ComponentActivity
|
||||
|
||||
// Permission state
|
||||
var hasStoragePermission by remember { mutableStateOf(false) }
|
||||
|
||||
// Check if permission is already granted
|
||||
// For Android 11+ (API 30+), check MANAGE_EXTERNAL_STORAGE
|
||||
// For Android 10 and below, check READ_EXTERNAL_STORAGE
|
||||
val permissionCheck = remember {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
// Android 11+ - check for MANAGE_EXTERNAL_STORAGE
|
||||
android.os.Environment.isExternalStorageManager()
|
||||
} else {
|
||||
// Android 10 and below - check for READ_EXTERNAL_STORAGE
|
||||
ContextCompat.checkSelfPermission(
|
||||
context,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
// Permission launcher for READ_EXTERNAL_STORAGE (Android 10 and below)
|
||||
val readStoragePermissionLauncher = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.RequestPermission()
|
||||
) { isGranted: Boolean ->
|
||||
hasStoragePermission = isGranted
|
||||
if (isGranted) {
|
||||
println("BATTLESCREEN: READ_EXTERNAL_STORAGE permission granted")
|
||||
} else {
|
||||
println("BATTLESCREEN: READ_EXTERNAL_STORAGE permission denied")
|
||||
}
|
||||
}
|
||||
|
||||
// Launcher for opening settings to grant MANAGE_EXTERNAL_STORAGE (Android 11+)
|
||||
val manageStorageSettingsLauncher = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.StartActivityForResult()
|
||||
) {
|
||||
// Re-check permission after returning from settings
|
||||
val hasPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
android.os.Environment.isExternalStorageManager()
|
||||
} else {
|
||||
ContextCompat.checkSelfPermission(
|
||||
context,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
hasStoragePermission = hasPermission
|
||||
if (hasPermission) {
|
||||
println("BATTLESCREEN: MANAGE_EXTERNAL_STORAGE permission granted")
|
||||
} else {
|
||||
println("BATTLESCREEN: MANAGE_EXTERNAL_STORAGE permission not granted")
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize permission state
|
||||
LaunchedEffect(Unit) {
|
||||
hasStoragePermission = permissionCheck
|
||||
if (!permissionCheck && activity != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
// Android 11+ - need to request MANAGE_EXTERNAL_STORAGE
|
||||
// This requires user to go to settings
|
||||
println("BATTLESCREEN: Android 11+ detected - opening settings for MANAGE_EXTERNAL_STORAGE")
|
||||
try {
|
||||
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
|
||||
intent.data = Uri.parse("package:${context.packageName}")
|
||||
manageStorageSettingsLauncher.launch(intent)
|
||||
} catch (e: Exception) {
|
||||
println("BATTLESCREEN: Error opening settings: ${e.message}")
|
||||
// Fallback: try the general manage external storage settings
|
||||
try {
|
||||
val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
|
||||
manageStorageSettingsLauncher.launch(intent)
|
||||
} catch (e2: Exception) {
|
||||
println("BATTLESCREEN: Error opening fallback settings: ${e2.message}")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Android 10 and below - request READ_EXTERNAL_STORAGE
|
||||
println("BATTLESCREEN: Requesting READ_EXTERNAL_STORAGE permission...")
|
||||
readStoragePermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
} else if (permissionCheck) {
|
||||
println("BATTLESCREEN: Storage permission already granted")
|
||||
}
|
||||
}
|
||||
|
||||
var currentView by remember { mutableStateOf("main") }
|
||||
|
||||
@ -1601,8 +1697,6 @@ fun BattlesScreen() {
|
||||
else -> rookieCharacters
|
||||
}
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
// Determine if player can battle based on stage (derived from activeUserCharacter)
|
||||
val canBattle = activeUserCharacter?.stage?.let { it >= 2 } ?: false
|
||||
|
||||
@ -1650,15 +1744,19 @@ fun BattlesScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize sprite files on first load
|
||||
LaunchedEffect(Unit) {
|
||||
// Initialize sprite files on first load - check that they exist in external storage
|
||||
// Only check if permission is granted
|
||||
LaunchedEffect(hasStoragePermission) {
|
||||
if (hasStoragePermission) {
|
||||
println("BATTLESCREEN: LaunchedEffect triggered - checking sprite files...")
|
||||
val spriteFileManager = SpriteFileManager(context)
|
||||
if (!spriteFileManager.checkSpriteFilesExist()) {
|
||||
println("BATTLESCREEN: Copying sprite files from external storage to internal storage...")
|
||||
spriteFileManager.copySpriteFilesToInternalStorage()
|
||||
if (spriteFileManager.checkSpriteFilesExist()) {
|
||||
println("BATTLESCREEN: Sprite files exist in external storage")
|
||||
} else {
|
||||
println("BATTLESCREEN: Sprite files already exist in internal storage")
|
||||
println("BATTLESCREEN: Sprite files not found in external storage")
|
||||
}
|
||||
} else {
|
||||
println("BATTLESCREEN: Cannot check sprite files - storage permission not granted")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1672,10 +1770,12 @@ fun BattlesScreen() {
|
||||
kotlinx.coroutines.withContext(Dispatchers.IO) {
|
||||
// First, let's check all characters to see what's in the database
|
||||
val allCharacters = database.userCharacterDao().getAllCharacters()
|
||||
/*
|
||||
println("BATTLESCREEN: Found ${allCharacters.size} total characters in database")
|
||||
allCharacters.forEach { char ->
|
||||
println(" - Character ID: ${char.id}, CharId: ${char.charId}")
|
||||
}
|
||||
*/
|
||||
|
||||
val activeChar = database.userCharacterDao().getActiveCharacter()
|
||||
println("BATTLESCREEN: getActiveCharacter() returned: $activeChar")
|
||||
@ -2211,10 +2311,11 @@ fun AnimatedBattleBackground(
|
||||
println("DEBUG: Screen dimensions = ${screenWidth.value}x${screenHeight.value}dp")
|
||||
}
|
||||
|
||||
// Load background image from internal storage
|
||||
// Load background image from external storage
|
||||
LaunchedEffect(Unit) {
|
||||
try {
|
||||
val backgroundFile = File(context.filesDir, "battle_sprites/extracted_battlebgs/BattleBg_0015_BattleBg_0012.png")
|
||||
val externalDir = android.os.Environment.getExternalStorageDirectory()
|
||||
val backgroundFile = File(externalDir, "VBHelper/battle_sprites/extracted_battlebgs/BattleBg_0015_BattleBg_0012.png")
|
||||
if (backgroundFile.exists()) {
|
||||
backgroundBitmap = BitmapFactory.decodeFile(backgroundFile.absolutePath)
|
||||
println("Successfully loaded battle background: ${backgroundFile.absolutePath}")
|
||||
@ -2317,13 +2418,14 @@ fun MultiLayerAnimatedBattleBackground(
|
||||
println("DEBUG: Multi-layer screen dimensions = ${screenWidth.value}x${screenHeight.value}dp")
|
||||
}
|
||||
|
||||
// Load all three background layers from internal storage
|
||||
// Load all three background layers from external storage
|
||||
LaunchedEffect(backgroundSetIndex) {
|
||||
try {
|
||||
val externalDir = android.os.Environment.getExternalStorageDirectory()
|
||||
val selectedSet = backgroundSets[backgroundSetIndex]
|
||||
|
||||
// Back layer
|
||||
val backLayerFile = File(context.filesDir, "battle_sprites/extracted_battlebgs/${selectedSet.backLayer}")
|
||||
val backLayerFile = File(externalDir, "VBHelper/battle_sprites/extracted_battlebgs/${selectedSet.backLayer}")
|
||||
if (backLayerFile.exists()) {
|
||||
backLayerBitmap = BitmapFactory.decodeFile(backLayerFile.absolutePath)
|
||||
println("Successfully loaded back layer background (Set ${backgroundSetIndex + 1}): ${backLayerFile.absolutePath}")
|
||||
@ -2332,7 +2434,7 @@ fun MultiLayerAnimatedBattleBackground(
|
||||
}
|
||||
|
||||
// Middle layer
|
||||
val middleLayerFile = File(context.filesDir, "battle_sprites/extracted_battlebgs/${selectedSet.middleLayer}")
|
||||
val middleLayerFile = File(externalDir, "VBHelper/battle_sprites/extracted_battlebgs/${selectedSet.middleLayer}")
|
||||
if (middleLayerFile.exists()) {
|
||||
middleLayerBitmap = BitmapFactory.decodeFile(middleLayerFile.absolutePath)
|
||||
println("Successfully loaded middle layer background (Set ${backgroundSetIndex + 1}): ${middleLayerFile.absolutePath}")
|
||||
@ -2341,7 +2443,7 @@ fun MultiLayerAnimatedBattleBackground(
|
||||
}
|
||||
|
||||
// Front layer
|
||||
val frontLayerFile = File(context.filesDir, "battle_sprites/extracted_battlebgs/${selectedSet.frontLayer}")
|
||||
val frontLayerFile = File(externalDir, "VBHelper/battle_sprites/extracted_battlebgs/${selectedSet.frontLayer}")
|
||||
if (frontLayerFile.exists()) {
|
||||
frontLayerBitmap = BitmapFactory.decodeFile(frontLayerFile.absolutePath)
|
||||
println("Successfully loaded front layer background (Set ${backgroundSetIndex + 1}): ${frontLayerFile.absolutePath}")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user