151 lines
5.4 KiB
Kotlin
151 lines
5.4 KiB
Kotlin
package jp.juggler.subwaytooter.actmain
|
|
|
|
import android.net.Uri
|
|
import android.os.Process
|
|
import android.util.JsonReader
|
|
import android.view.WindowManager
|
|
import androidx.annotation.WorkerThread
|
|
import jp.juggler.subwaytooter.ActMain
|
|
import jp.juggler.subwaytooter.R
|
|
import jp.juggler.subwaytooter.appsetting.AppDataExporter
|
|
import jp.juggler.subwaytooter.column.Column
|
|
import jp.juggler.subwaytooter.notification.setImportProtector
|
|
import jp.juggler.util.LogCategory
|
|
import jp.juggler.util.runOnMainLooper
|
|
import jp.juggler.util.launchProgress
|
|
import jp.juggler.util.showToast
|
|
import java.io.File
|
|
import java.io.FileInputStream
|
|
import java.io.FileOutputStream
|
|
import java.io.InputStreamReader
|
|
import java.util.zip.ZipInputStream
|
|
|
|
private val log = LogCategory("ActMainImportAppData")
|
|
|
|
@WorkerThread
|
|
fun ActMain.importAppData(uri: Uri) {
|
|
|
|
// remove all columns
|
|
phoneOnly { env -> env.pager.adapter = null }
|
|
|
|
appState.editColumnList(save = false) { list ->
|
|
list.forEach { it.dispose() }
|
|
list.clear()
|
|
}
|
|
|
|
phoneTab(
|
|
{ env -> env.pager.adapter = env.pagerAdapter },
|
|
{ env -> resizeColumnWidth(env) }
|
|
)
|
|
|
|
updateColumnStrip()
|
|
|
|
launchProgress(
|
|
"importing app data",
|
|
doInBackground = { progress ->
|
|
fun setProgressMessage(sv: String) = runOnMainLooper { progress.setMessageEx(sv) }
|
|
|
|
setProgressMessage("import data to local storage...")
|
|
|
|
// アプリ内領域に一時ファイルを作ってコピーする
|
|
val cacheDir = cacheDir
|
|
cacheDir.mkdir()
|
|
val file = File(cacheDir, "SubwayTooter.${Process.myPid()}.${Process.myTid()}.tmp")
|
|
val copyBytes = contentResolver.openInputStream(uri)?.let { inStream ->
|
|
FileOutputStream(file).use { outStream ->
|
|
inStream.copyTo(outStream)
|
|
}
|
|
}
|
|
if (copyBytes == null) {
|
|
showToast(true, "openInputStream failed.")
|
|
return@launchProgress null
|
|
}
|
|
|
|
// 通知サービスを止める
|
|
setProgressMessage("syncing notification poller…")
|
|
setImportProtector(this@importAppData, true)
|
|
|
|
// データを読み込む
|
|
setProgressMessage("reading app data...")
|
|
var newColumnList: ArrayList<Column>? = null
|
|
var zipEntryCount = 0
|
|
try {
|
|
ZipInputStream(FileInputStream(file)).use { zipStream ->
|
|
while (true) {
|
|
val entry = zipStream.nextEntry ?: break
|
|
++zipEntryCount
|
|
try {
|
|
//
|
|
val entryName = entry.name
|
|
if (entryName.endsWith(".json")) {
|
|
newColumnList = AppDataExporter.decodeAppData(
|
|
this@importAppData,
|
|
JsonReader(InputStreamReader(zipStream, "UTF-8"))
|
|
)
|
|
continue
|
|
}
|
|
|
|
if (AppDataExporter.restoreBackgroundImage(
|
|
this@importAppData,
|
|
newColumnList,
|
|
zipStream,
|
|
entryName
|
|
)
|
|
) {
|
|
continue
|
|
}
|
|
} finally {
|
|
zipStream.closeEntry()
|
|
}
|
|
}
|
|
}
|
|
} catch (ex: Throwable) {
|
|
log.trace(ex)
|
|
if (zipEntryCount != 0) {
|
|
showToast(ex, "importAppData failed.")
|
|
}
|
|
}
|
|
// zipではなかった場合、zipEntryがない状態になる。例外はPH-1では出なかったが、出ても問題ないようにする。
|
|
if (zipEntryCount == 0) {
|
|
InputStreamReader(FileInputStream(file), "UTF-8").use { inStream ->
|
|
newColumnList =
|
|
AppDataExporter.decodeAppData(this@importAppData, JsonReader(inStream))
|
|
}
|
|
}
|
|
|
|
newColumnList
|
|
},
|
|
afterProc = {
|
|
// cancelled.
|
|
if (it == null) return@launchProgress
|
|
|
|
try {
|
|
phoneOnly { env -> env.pager.adapter = null }
|
|
|
|
appState.editColumnList { list ->
|
|
list.clear()
|
|
list.addAll(it)
|
|
}
|
|
|
|
phoneTab(
|
|
{ env -> env.pager.adapter = env.pagerAdapter },
|
|
{ env -> resizeColumnWidth(env) }
|
|
)
|
|
updateColumnStrip()
|
|
} finally {
|
|
// 通知サービスをリスタート
|
|
setImportProtector(this@importAppData, false)
|
|
}
|
|
|
|
showToast(true, R.string.import_completed_please_restart_app)
|
|
finish()
|
|
},
|
|
preProc = {
|
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
},
|
|
postProc = {
|
|
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
}
|
|
)
|
|
}
|