diff --git a/app/src/main/java/com/kyhsgeekcode/dereinfo/SerializableSparseArray.kt b/app/src/main/java/com/kyhsgeekcode/dereinfo/SerializableSparseArray.kt new file mode 100644 index 0000000..bbb6e5c --- /dev/null +++ b/app/src/main/java/com/kyhsgeekcode/dereinfo/SerializableSparseArray.kt @@ -0,0 +1,67 @@ +package com.kyhsgeekcode.dereinfo + +import android.util.SparseArray +import java.io.IOException +import java.io.ObjectInputStream +import java.io.ObjectOutputStream + +typealias SerializableSparseIntArray = SerializableSparseArray + +class SerializableSparseArray : SparseArray, java.io.Serializable { + + constructor() : super() + constructor(capacity: Int) : super(capacity) + + /** + * This method is private but it is called using reflection by java + * serialization mechanism. It overwrites the default object serialization. + * + *



**IMPORTANT** + * The access modifier for this method MUST be set to **private** otherwise [java.io.StreamCorruptedException] + * will be thrown. + * + * @param oos + * the stream the data is stored into + * @throws IOException + * an exception that might occur during data storing + */ + @Throws(IOException::class) + private fun writeObject(oos: ObjectOutputStream) { + val data = arrayOfNulls(size()) + for (i in data.indices) { + val pair = Pair(keyAt(i), valueAt(i)) + data[i] = pair + } + oos.writeObject(data) + } + + /** + * This method is private but it is called using reflection by java + * serialization mechanism. It overwrites the default object serialization. + * + *



**IMPORTANT** + * The access modifier for this method MUST be set to **private** otherwise [java.io.StreamCorruptedException] + * will be thrown. + * + * @param oos + * the stream the data is read from + * @throws IOException + * an exception that might occur during data reading + * @throws ClassNotFoundException + * this exception will be raised when a class is read that is + * not known to the current ClassLoader + */ + @Throws(IOException::class, ClassNotFoundException::class) + private fun readObject(ois: ObjectInputStream) { + val data = ois.readObject() as Array + for (i in data.indices) { + val pair = data[i] as Pair + this.append(pair.first, pair.second) + } + return + } + + companion object { + private const val serialVersionUID = 824056059663678000L + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kyhsgeekcode/dereinfo/SongDetailFragment.kt b/app/src/main/java/com/kyhsgeekcode/dereinfo/SongDetailFragment.kt index 326b8f7..4caafba 100644 --- a/app/src/main/java/com/kyhsgeekcode/dereinfo/SongDetailFragment.kt +++ b/app/src/main/java/com/kyhsgeekcode/dereinfo/SongDetailFragment.kt @@ -43,7 +43,8 @@ class SongDetailFragment : Fragment() { activity?.toolbar_layout?.title = item?.name?.replace("\\n", " ") activity?.toolbar_layout?.setBackgroundColor(item?.getColor() ?: 0xFFDDDDDD.toInt()) val musicNumber = DereDatabaseHelper.theInstance.musicIDTomusicNumber[item!!.id] - oneMusic = DereDatabaseHelper.theInstance.peekFumens(musicNumber) + Log.w(TAG, "Item.id:${item!!.id}, musicNumber:${musicNumber}") + oneMusic = DereDatabaseHelper.theInstance.peekFumens(musicNumber!!) } } } diff --git a/app/src/main/java/com/kyhsgeekcode/dereinfo/Utils.kt b/app/src/main/java/com/kyhsgeekcode/dereinfo/Utils.kt index 7e45b91..98b2e9f 100644 --- a/app/src/main/java/com/kyhsgeekcode/dereinfo/Utils.kt +++ b/app/src/main/java/com/kyhsgeekcode/dereinfo/Utils.kt @@ -45,7 +45,13 @@ val sqliteHeader = byteArrayOf( ) fun checkIfDatabase(file: File): Boolean { + if(file==null) + return false + if(file.isDirectory) + return false val byteArray = ByteArray(16) - file.inputStream().read(byteArray, 0, 16) + val fi = file.inputStream() + fi.read(byteArray, 0, 16) + fi.close() return byteArray contentEquals sqliteHeader } \ No newline at end of file diff --git a/app/src/main/java/com/kyhsgeekcode/dereinfo/model/DereDatabaseHelper.kt b/app/src/main/java/com/kyhsgeekcode/dereinfo/model/DereDatabaseHelper.kt index 5ec3964..e8fdf79 100644 --- a/app/src/main/java/com/kyhsgeekcode/dereinfo/model/DereDatabaseHelper.kt +++ b/app/src/main/java/com/kyhsgeekcode/dereinfo/model/DereDatabaseHelper.kt @@ -5,8 +5,9 @@ import android.database.Cursor import android.database.SQLException import android.database.sqlite.SQLiteDatabase import android.util.Log -import android.util.SparseIntArray +import androidx.core.util.set import com.github.doyaaaaaken.kotlincsv.dsl.csvReader +import com.kyhsgeekcode.dereinfo.SerializableSparseIntArray import com.kyhsgeekcode.dereinfo.checkIfDatabase import com.kyhsgeekcode.dereinfo.loadObject import com.kyhsgeekcode.dereinfo.model.CircleType.getColor @@ -26,8 +27,8 @@ class DereDatabaseHelper(context: Context) { val fumenFolder: File var musicIDToInfo: MutableMap = HashMap() - val musicNumberToMusicID: SparseIntArray = SparseIntArray() - val musicIDTomusicNumber = SparseIntArray() + var musicNumberToMusicID = HashMap() //SerializableSparseIntArray = SerializableSparseIntArray() + var musicIDTomusicNumber = HashMap() // = SerializableSparseIntArray() init { val datadir = context.getExternalFilesDir(null).parentFile.parentFile @@ -71,8 +72,8 @@ class DereDatabaseHelper(context: Context) { fumensDB.query( "live_data", arrayOf("id", "music_data_id", "circle_type"), - null, - null, + "end_date=?", + arrayOf(""), null, null, null @@ -127,6 +128,7 @@ class DereDatabaseHelper(context: Context) { val circleType = cursorLiveData.getInt(circleTypeIndex) musicNumberToMusicID[liveDataId] = musicDataId musicIDTomusicNumber[musicDataId] = liveDataId + //Log.w(TAG, "musicIDToMusicNumber[${musicDataId}]=${liveDataId}") val musicInfo = MusicInfo( musicDataId, name, @@ -168,18 +170,28 @@ class DereDatabaseHelper(context: Context) { name = name.substring(13) name = name.substringBefore('.') val musicIndex = Integer.parseInt(name.split('/')[0]) - //Log.d(TAG, "musicIndex ${musicIndex}") + // Log.d(TAG, "musicIndex ${musicIndex}, ${file.name}") // val difficulty = Integer.parseInt(name.substringAfter('_')) musicNumberToFumenFile[musicIndex] = file break } fumenDB.close() } catch (e: SQLException) { + Log.e(TAG, "indexFumen",e) continue } finally { cursorFumens?.close() } } + + //check validity(debug) +// for(item in musicIDToInfo.values) { +// val musicNumber = musicIDTomusicNumber[item.id] +// //Log.w(TAG, "Item.id:${item.id}, musicNumber:${musicNumber}") +// val file = musicNumberToFumenFile[musicNumber] +// if(file != null) +// Log.w(TAG,"id:${item.id},name:${item.name},file:${file?.name}") +// } } @@ -189,6 +201,11 @@ class DereDatabaseHelper(context: Context) { val indexToFumenFileFilename = "indexToFumenFile.dat" val musicInfoFile = File(context.filesDir, musicInfoFilename) val indexToFumenFileFile = File(context.filesDir, indexToFumenFileFilename) + val musicNumberToMusicIDFileName = "musicNumberToMusicID.dat" + val musicNumberToMusicIDFile = File(context.filesDir, musicNumberToMusicIDFileName) + val musicIDToMusicNumberFileName = "musicIDToMusicNumber.dat" + val musicIDToMusicNumberFile = File(context.filesDir, musicIDToMusicNumberFileName) + private fun saveToCache(context: Context) { // searchMainDB() @@ -196,6 +213,8 @@ class DereDatabaseHelper(context: Context) { saveObject(mainDBFileCacheFile, fumensDBFile) saveObject(musicInfoFile, musicIDToInfo) saveObject(indexToFumenFileFile, musicNumberToFumenFile) + saveObject(musicNumberToMusicIDFile, musicNumberToMusicID) + saveObject(musicIDToMusicNumberFile, musicIDTomusicNumber) } private fun loadFromCache(context: Context): Boolean { @@ -207,6 +226,7 @@ class DereDatabaseHelper(context: Context) { return false return true } catch (e: Exception) { + Log.e(TAG, "error loading", e) return false } } @@ -215,6 +235,8 @@ class DereDatabaseHelper(context: Context) { loadFumenDBFileFromCache() musicIDToInfo = loadObject(musicInfoFile) as MutableMap musicNumberToFumenFile = loadObject(indexToFumenFileFile) as MutableMap + musicNumberToMusicID = loadObject(musicNumberToMusicIDFile) as HashMap //as SerializableSparseIntArray + musicIDTomusicNumber = loadObject(musicIDToMusicNumberFile) as HashMap //SerializableSparseIntArray } private fun loadFumenDBFileFromCache() { @@ -260,9 +282,14 @@ class DereDatabaseHelper(context: Context) { //5개를 파싱해라. fun peekFumens(musicNumber: Int): OneMusic { -// Log.d(TAG, "musicIndex : ${musicNumber},indexToFumenFile size:${musicNumberToFumenFile.size}") + Log.d( + TAG, + "musicIndex : ${musicNumber},indexToFumenFile size:${musicNumberToFumenFile.size}" + ) val fumenFile = musicNumberToFumenFile[musicNumber] Log.d(TAG, "fumenFile:${fumenFile?.name}") + if(fumenFile==null) + throw java.lang.RuntimeException() val fumenDB = SQLiteDatabase.openDatabase(fumenFile!!.path, null, SQLiteDatabase.OPEN_READONLY) val cursorFumens = @@ -281,12 +308,12 @@ class DereDatabaseHelper(context: Context) { var name = cursorFumens.getString(0) if (!name[name.length - 5].isDigit()) continue - Log.d(TAG, "name:${name}") + //Log.d(TAG, "name:${name}") name = name.substring(13) name = name.substringBefore('.') // Log.d(TAG,"name:${name}") val difficulty = Integer.parseInt(name.substringAfter('_')) - Log.d(TAG, "difficulty:${difficulty}") + //Log.d(TAG, "difficulty:${difficulty}") val twDifficulty = TW5Difficulty.valueOf(difficulty) difficulties[twDifficulty] = OneDifficulty(twDifficulty, null) }