diff --git a/app/src/main/java/com/duolebo/blyrobot/data/ImageUploadTask.kt b/app/src/main/java/com/duolebo/blyrobot/data/ImageUploadTask.kt index 37cbee2654a62de5bc17f3c33c11232c8abf9202..acb190adee7f1d92befd42848c3aef7157408f9a 100644 --- a/app/src/main/java/com/duolebo/blyrobot/data/ImageUploadTask.kt +++ b/app/src/main/java/com/duolebo/blyrobot/data/ImageUploadTask.kt @@ -2,11 +2,15 @@ package com.duolebo.blyrobot.data import android.content.Context import android.util.Log +import com.duolebo.blyrobot.tools.FtpManager +import com.duolebo.blyrobot.util.AppUtil import com.duolebo.blyrobot.util.Config import net.gotev.uploadservice.* import net.gotev.uploadservice.ftp.FTPUploadRequest import net.gotev.uploadservice.ftp.UnixPermissions import java.io.File +import java.util.* +import kotlin.collections.ArrayList /** * 图片上传任务 @@ -24,6 +28,10 @@ class ImageUploadTask { var isRunning = false private var context: Context + private var uploadCheckTimer: Timer? = null + private var isUploadChecking = false + private var checkDelay = 5 * 60 * 1000L + private var checkCount = 0 constructor(context: Context) { this.context = context @@ -45,6 +53,9 @@ class ImageUploadTask { if (isUploadRunning()) return false + if (this.isUploadChecking) + return false + return true } @@ -58,8 +69,85 @@ class ImageUploadTask { } fun start() { + + if (this.uploadImages.isEmpty()) { + uploadTaskListener?.onComplete() + return + } + this.isRunning = true Thread { uploadImage() }.start() + + // 预计每张图片上传时间是3秒 + startUploadCheck(3 * 1000L * this.uploadImages.size) + } + + // 由于ftp库存在bug,这里启动一个定时器进行超时上传检测 + private fun startUploadCheck(delay: Long) { + Log.i(TAG, "startUploadCheck with delay: $delay") + this.checkDelay = delay + uploadCheckTimer?.cancel() + + if (this.checkCount >= 3) { + Log.i(TAG, "check time out, quit this job") + uploadTaskListener?.onComplete() + return + } + + uploadCheckTimer = Timer() + uploadCheckTimer!!.schedule(object : TimerTask() { + override fun run() { + checkUpload() + } + }, delay) + + this.checkCount++ + } + + private fun checkUpload() { + Log.i(TAG, "check image upload") + if (isUploadRunning()) { + startUploadCheck(this.checkDelay / 3) + return + } + + this.isUploadChecking = true + val lastUploadPos = getLastUploadImagePos() + Log.i(TAG, "get last upload pos:$lastUploadPos") + val size = this.uploadImages.size + // 移除所有已经上传的图片 + val reUploadImages = this.uploadImages.subList(lastUploadPos, size - 1) + this.uploadImages.removeAll(reUploadImages) + this.reUpload = true + this.isUploadChecking = false + } + + // 通过检查url是否存在找到最后上传图片的位置 + private fun getLastUploadImagePos(): Int { + val res: Int + val size = this.uploadImages.size + var checkPos = size / 2 + var halfPos = checkPos + while (true) { + val exist = AppUtil.existsUrl(this.uploadImages[checkPos]) + if (exist) { + checkPos += halfPos / 2 + } else { + checkPos -= halfPos / 2 + } + + halfPos /= 2 + + if (halfPos == 0) { + res = if (exist) + checkPos + else + checkPos - 1 + break + } + } + + return res } private fun uploadImage() { @@ -74,13 +162,21 @@ class ImageUploadTask { .setDelegate(uploadImageCallback()) .setMaxRetries(4) + val unExistFiles = ArrayList() this.uploadImages.forEach { val uploadFile = File(it) if (uploadFile.exists()) { uploadRequest.addFileToUpload(it, Config.instance.getFtpRemotePath() + uploadFile.name) + } else { + unExistFiles.add(it) } } + // 删除不存在的图片记录 + if (!unExistFiles.isEmpty()) { + this.uploadImages.removeAll(unExistFiles) + } + this.uploadId = uploadRequest.startUpload() Log.i(TAG, "upload id $uploadId") } catch (exc: Exception) { @@ -90,6 +186,7 @@ class ImageUploadTask { private fun uploadComplete(errorCount: Int) { Log.i(TAG, "upload errorCount: $errorCount") + uploadCheckTimer?.cancel() this.isRunning = false if (errorCount > 0 && errorCount > this.uploadImages.size / 3) { this.reUpload = true @@ -104,7 +201,6 @@ class ImageUploadTask { } uploadTaskListener?.onComplete() - } /** diff --git a/app/src/main/java/com/duolebo/blyrobot/util/AppUtil.kt b/app/src/main/java/com/duolebo/blyrobot/util/AppUtil.kt index 89b235df39974e49f18f22e0ca735c651e2c6a6c..84162a13349777792391bee0233d4a3f5cb9e589 100644 --- a/app/src/main/java/com/duolebo/blyrobot/util/AppUtil.kt +++ b/app/src/main/java/com/duolebo/blyrobot/util/AppUtil.kt @@ -23,8 +23,6 @@ import android.R.attr.versionName import android.content.pm.PackageInfo - - object AppUtil { fun deleteFile(file: File?, fileFilter: FileFilter) { @@ -229,7 +227,7 @@ object AppUtil { } } - fun exists(url: String): Boolean { + fun existsUrl(url: String): Boolean { return try { HttpURLConnection.setFollowRedirects(false) val con = URL(url).openConnection() as HttpURLConnection