163 lines
6.1 KiB
Kotlin
163 lines
6.1 KiB
Kotlin
|
package jp.juggler.subwaytooter
|
||
|
|
||
|
import android.net.Uri
|
||
|
import android.os.Process
|
||
|
import android.util.JsonReader
|
||
|
import android.view.WindowManager
|
||
|
import androidx.annotation.WorkerThread
|
||
|
import jp.juggler.subwaytooter.notification.PollingWorker
|
||
|
import jp.juggler.util.launchMain
|
||
|
import jp.juggler.util.runOnMainLooper
|
||
|
import jp.juggler.util.runWithProgress
|
||
|
import jp.juggler.util.showToast
|
||
|
import kotlinx.coroutines.delay
|
||
|
import org.apache.commons.io.IOUtils
|
||
|
import java.io.File
|
||
|
import java.io.FileInputStream
|
||
|
import java.io.FileOutputStream
|
||
|
import java.io.InputStreamReader
|
||
|
import java.util.ArrayList
|
||
|
import java.util.zip.ZipInputStream
|
||
|
|
||
|
@WorkerThread
|
||
|
fun ActMain.importAppData(uri: Uri) {
|
||
|
launchMain {
|
||
|
|
||
|
// 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()
|
||
|
|
||
|
runWithProgress(
|
||
|
"importing app data",
|
||
|
|
||
|
doInBackground = { progress ->
|
||
|
fun setProgressMessage(sv: String) =
|
||
|
runOnMainLooper { progress.setMessageEx(sv) }
|
||
|
|
||
|
var newColumnList: ArrayList<Column>? = null
|
||
|
|
||
|
setProgressMessage("import data to local storage...")
|
||
|
|
||
|
// アプリ内領域に一時ファイルを作ってコピーする
|
||
|
val cacheDir = cacheDir
|
||
|
cacheDir.mkdir()
|
||
|
val file = File(
|
||
|
cacheDir,
|
||
|
"SubwayTooter.${Process.myPid()}.${Process.myTid()}.tmp"
|
||
|
)
|
||
|
val source = contentResolver.openInputStream(uri)
|
||
|
if (source == null) {
|
||
|
showToast(true, "openInputStream failed.")
|
||
|
return@runWithProgress null
|
||
|
}
|
||
|
source.use { inStream ->
|
||
|
FileOutputStream(file).use { outStream ->
|
||
|
IOUtils.copy(inStream, outStream)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 通知サービスを止める
|
||
|
setProgressMessage("syncing notification poller…")
|
||
|
PollingWorker.queueAppDataImportBefore(this@importAppData)
|
||
|
while (PollingWorker.mBusyAppDataImportBefore.get()) {
|
||
|
delay(1000L)
|
||
|
ActMain.log.d("syncing polling task...")
|
||
|
}
|
||
|
|
||
|
// データを読み込む
|
||
|
setProgressMessage("reading app data...")
|
||
|
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) {
|
||
|
ActMain.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@runWithProgress
|
||
|
|
||
|
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 {
|
||
|
// 通知サービスをリスタート
|
||
|
PollingWorker.queueAppDataImportAfter(this@importAppData)
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
)
|
||
|
}
|
||
|
}
|