diff --git a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt index c9829eb..506ead8 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt @@ -87,17 +87,17 @@ object TestUtils { } fun testUploadFile(uploadApi: UploadFileApi, video: Video, commonDialog: CommonDialog?) { - val path = video.path - uploadApi.singleUpload(path, System.currentTimeMillis(), object : - RequestResultCallBack() { - override fun onResult(result: BaseResponse) { - commonDialog?.dismiss() - } - - override fun onError(error: String?) { - commonDialog?.dismiss() - } - }) +// val path = video.path +// uploadApi.singleUpload(path, System.currentTimeMillis(), object : +// RequestResultCallBack() { +// override fun onResult(result: BaseResponse) { +// commonDialog?.dismiss() +// } +// +// override fun onError(error: String?) { +// commonDialog?.dismiss() +// } +// }) } fun testExportExcel(context: Context, datas: MutableList, commonDialog: CommonDialog?) { diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/base/BaseActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/base/BaseActivity.kt index 72c7cd0..eba4a5d 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/base/BaseActivity.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/base/BaseActivity.kt @@ -77,6 +77,7 @@ abstract class BaseActivity : AppCompatActivity() { fun closeLoadingDialog() { loadingDialog?.dismiss() + loadingDialog = null } open val isHome: Boolean = false @@ -132,4 +133,9 @@ abstract class BaseActivity : AppCompatActivity() { fun tryFocusBackArea() { baseBinding.topBar.tryFocusBackArea() } + + override fun onDestroy() { + super.onDestroy() + closeLoadingDialog() + } } \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/constant/Constants.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/constant/Constants.kt index d450d2f..7d09109 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/constant/Constants.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/constant/Constants.kt @@ -21,4 +21,4 @@ const val DELAY_TIME_CHECK_CAMERA = 5 const val NAMESPACE_ANDROID = "http://schemas.android.com/apk/res/android" // 云同步时,20条数据已上传 -const val GAS_CLOUD_UPLOAD_SIZE_ONCE = 20; \ No newline at end of file +const val GAS_CLOUD_UPLOAD_SIZE_ONCE = 20 \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/net/DevicesApi.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/net/DevicesApi.kt index b4e0622..90e9192 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/net/DevicesApi.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/net/DevicesApi.kt @@ -42,24 +42,23 @@ class DevicesApi : BaseObserve(Api::class.java) { observe(api.updateTrafficInfo(trafficReqInfo), null) } - fun uploadGasData( - gasList: List = emptyList(), - callBack: RequestResultCallBack - ) { + suspend fun uploadGasData( + gasList: List = emptyList() + ): BaseResponse { val detections = arrayListOf() gasList.forEach { detections.add(GasReqBean(it)) } val gasReq = GasRequest(detections = detections) - observe(api.uploadGasData(gasReq), callBack) + return api.uploadGasData(gasReq) } - fun getDetectionLastTime(callBack: RequestResultCallBack) { - observe(api.getDetectionLastTime(LztekUtil.getSn()), callBack) + suspend fun getDetectionLastTime() : LastTimeResponse{ + return api.getDetectionLastTime(LztekUtil.getSn()) } - fun getVideoLastTime(callBack: RequestResultCallBack) { - observe(api.getVideoLastTime(LztekUtil.getSn()), callBack) + suspend fun getVideoLastTime(): LastTimeResponse { + return api.getVideoLastTime(LztekUtil.getSn()) } interface Api { @@ -78,14 +77,14 @@ class DevicesApi : BaseObserve(Api::class.java) { @Headers("baseurl:host") @POST("/api/device/addDetection") - fun uploadGasData(@Body body: GasRequest): Observable + suspend fun uploadGasData(@Body body: GasRequest): BaseResponse @Headers("baseurl:host") @GET("/api/device/getDetectionLastTime") - fun getDetectionLastTime(@Query("deviceSn") sn: String): Observable + suspend fun getDetectionLastTime(@Query("deviceSn") sn: String): LastTimeResponse @Headers("baseurl:host") @GET("/api/device/getVideoLastTime") - fun getVideoLastTime(@Query("deviceSn") sn: String): Observable + suspend fun getVideoLastTime(@Query("deviceSn") sn: String): LastTimeResponse } } \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/net/UploadFileApi.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/net/UploadFileApi.kt index 878ebb3..d233835 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/net/UploadFileApi.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/net/UploadFileApi.kt @@ -2,9 +2,7 @@ package com.yinuo.safetywatcher.watcher.net import com.common.commonlib.net.BaseObserve import com.common.commonlib.net.bean.BaseResponse -import com.common.commonlib.net.callback.RequestResultCallBack import com.yinuo.safetywatcher.watcher.utils.LztekUtil -import io.reactivex.rxjava3.core.Observable import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody import okhttp3.RequestBody @@ -24,25 +22,21 @@ const val FORM_DATA = "multipart/form-data"; */ class UploadFileApi : BaseObserve(Api::class.java) { - open fun singleUpload( + suspend fun singleUpload( path: String, - videoTime: Long, - callBack: RequestResultCallBack - ) { - observe( - api.singleUpload(makeParamsMaps(videoTime), makeFileBodyPart(path)), - callBack - ) + videoTime: Long + ): BaseResponse { + return api.singleUpload(makeParamsMaps(videoTime), makeFileBodyPart(path)) } interface Api { @Headers("baseurl:host") @Multipart @POST("/common/uploadVideo") - fun singleUpload( + suspend fun singleUpload( @PartMap params: Map, @Part file: MultipartBody.Part - ): Observable + ): BaseResponse } private fun makeFileBodyPart(path: String): MultipartBody.Part { diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/CloudActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/CloudActivity.kt index acb02fb..55f3cbf 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/CloudActivity.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/CloudActivity.kt @@ -6,20 +6,18 @@ import android.view.View import com.common.commonlib.db.DBUtils import com.common.commonlib.db.entity.Gas import com.common.commonlib.db.entity.Video -import com.common.commonlib.net.bean.BaseResponse -import com.common.commonlib.net.callback.RequestResultCallBack import com.yinuo.library.vlc.utils.LogUtils import com.yinuo.safetywatcher.R -import com.yinuo.safetywatcher.TestUtils import com.yinuo.safetywatcher.databinding.ActivityCloudBinding import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity -import com.yinuo.safetywatcher.watcher.bean.LastTimeResponse import com.yinuo.safetywatcher.watcher.constant.GAS_CLOUD_UPLOAD_SIZE_ONCE import com.yinuo.safetywatcher.watcher.net.DevicesApi import com.yinuo.safetywatcher.watcher.net.UploadFileApi +import com.yinuo.safetywatcher.watcher.utils.showToast import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch +import java.util.concurrent.atomic.AtomicBoolean class CloudActivity : NoOptionsActivity() { private val mBinding: ActivityCloudBinding by lazy { @@ -34,7 +32,10 @@ class CloudActivity : NoOptionsActivity() { DevicesApi() } - override fun getTopBarTitle(): String? { + private var uploadingGas = AtomicBoolean(false) + private var uploadingVideo = AtomicBoolean(false) + + override fun getTopBarTitle(): String { return getString(R.string.cloud) } @@ -45,14 +46,32 @@ class CloudActivity : NoOptionsActivity() { override fun initView() { mBinding.apply { syncSensor.setOnClickListener { + if (uploadingGas.get()) { + showToast(getString(R.string.repeat_click_sync_tip)) + return@setOnClickListener + } showLoadingDialog() - uploadSensorData() + GlobalScope.launch { + uploadSensorData() + closeLoadingDialog() + } } syncVedio.setOnClickListener { + if (uploadingVideo.get()) { + showToast(getString(R.string.repeat_click_sync_tip)) + return@setOnClickListener + } showLoadingDialog() - uploadVideo() + GlobalScope.launch { + uploadVideo() + closeLoadingDialog() + } } syncOnce.setOnClickListener { + if (uploadingGas.get() && uploadingVideo.get()) { + showToast(getString(R.string.repeat_click_sync_tip)) + return@setOnClickListener + } showLoadingDialog() uploadOnece() } @@ -60,98 +79,92 @@ class CloudActivity : NoOptionsActivity() { } private fun uploadOnece() { - uploadSensorData() - uploadVideo() + GlobalScope.launch { + uploadSensorData() + uploadVideo() + closeLoadingDialog() + } } - private fun uploadVideo() { - // 1.拿到云端最新数据时间 - devicesApi.getVideoLastTime(object : RequestResultCallBack() { - override fun onResult(result: LastTimeResponse) { - if (result.isOk()) { - val cloudTime = result.data - // 2. 拿到待上传文件列表 上传 - getFileListAndUpload(cloudTime) - } else { - LogUtils.e("getVideoLastTime error code = ${result.code}") - } - } - - override fun onError(error: String?) { - LogUtils.e(error) + private suspend fun uploadVideo() { + if (!uploadingVideo.get()) { + uploadingVideo.set(true) + // 1.拿到云端最新数据时间 + val timeResponse = devicesApi.getVideoLastTime() + if (timeResponse.isOk()) { + val cloudTime = timeResponse.data + // 2. 拿到待上传文件列表 上传 + getFileListAndUpload(cloudTime) + LogUtils.v("uploadVideo ok") + } else { + LogUtils.e("getVideoLastTime error code = ${timeResponse.code}") } - }) + uploadingVideo.set(false) + } } - private fun uploadSensorData() { - // 1.拿到云端最新数据时间 - devicesApi.getVideoLastTime(object : RequestResultCallBack() { - override fun onResult(result: LastTimeResponse) { - if (result.isOk()) { - val cloudTime = result.data - // 2. 查询本地数据库中该时间之后的数据 - // 3. 上传数据给服务器 - getSensorDataUpload(cloudTime) - } else { - LogUtils.e("getVideoLastTime error code = ${result.code}") - } - } - - override fun onError(error: String?) { - LogUtils.e(error) + private suspend fun uploadSensorData() { + if (!uploadingGas.get()) { + uploadingGas.set(true) + // 1.拿到云端最新数据时间 + val lastTimeResponse = devicesApi.getDetectionLastTime() + if (lastTimeResponse.isOk()) { + val cloudTime = lastTimeResponse.data + // 2. 查询本地数据库中该时间之后的数据 + // 3. 上传数据给服务器 + getSensorDataUpload(cloudTime) + LogUtils.v("uploadSensorData ok") + } else { + LogUtils.e("getVideoLastTime error code = ${lastTimeResponse.code}") } - }) + uploadingGas.set(false) + } } - private fun getSensorDataUpload(cloudTime: Long) { - GlobalScope.launch { - val gasList = DBUtils.gasDao().getAllBySyncFlagOrTime(false, cloudTime) - val tempList = arrayListOf() - gasList.forEach { - tempList.add(it) - if (tempList.size == GAS_CLOUD_UPLOAD_SIZE_ONCE) { - val cloneList: ArrayList = tempList.clone() as ArrayList - devicesApi.uploadGasData(cloneList, UploadGasCallback(tempList)) - tempList.clear() + private suspend fun getSensorDataUpload(cloudTime: Long) { + val gasList = DBUtils.gasDao().getAllBySyncFlagOrTime(false, cloudTime) + val tempList = arrayListOf() + gasList.forEach { + tempList.add(it) + if (tempList.size == GAS_CLOUD_UPLOAD_SIZE_ONCE) { + val response = devicesApi.uploadGasData(tempList) + if (response.isOk()) { + val gasDao = DBUtils.gasDao() + tempList.forEach { gas -> + gas.syncFlag = true + gasDao.update(gas) + } } - } - if (tempList.isNotEmpty()) { - devicesApi.uploadGasData(tempList, UploadGasCallback(tempList)) + tempList.clear() } } - } - - private fun getFileListAndUpload(cloudTime: Long) { - GlobalScope.launch { - val videoDao = DBUtils.videoDao() - val videoList = videoDao.getAllByTime(cloudTime, System.currentTimeMillis()) - // 上传 - videoList.forEach { - uploadFile(it) + if (tempList.isNotEmpty()) { + val response = devicesApi.uploadGasData(tempList) + if (response.isOk()) { + val gasDao = DBUtils.gasDao() + tempList.forEach { + it.syncFlag = true + gasDao.update(it) + } } } } - private fun uploadFile(video: Video) { - TestUtils.testUploadFile(uploadApi, video, loadingDialog) - } - - class UploadGasCallback(private val upLoadList: ArrayList) : - RequestResultCallBack() { - override fun onResult(result: BaseResponse) { - GlobalScope.launch { - if (result.isOk()) { - val gasDao = DBUtils.gasDao() - upLoadList.forEach { - it.syncFlag = true - gasDao.update(it) - } - } - } + private suspend fun getFileListAndUpload(cloudTime: Long) { + val videoDao = DBUtils.videoDao() + val videoList = videoDao.getAllByTime(cloudTime, System.currentTimeMillis()) + // 上传 + videoList.forEach { + uploadFile(it) } + } - override fun onError(error: String?) { - LogUtils.e("UploadGasCallback $error") + private suspend fun uploadFile(video: Video) { + val response = uploadApi.singleUpload(video.path, video.time) + if (response.isOk()) { + val videoDaoImpl = DBUtils.videoDao() + video.uploaded = true + videoDaoImpl.update(video) } } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 25a3ba6..af546ca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -57,4 +57,5 @@ 数据导出中 正在连接摄像头... + 正在同步中,请勿重复点击 diff --git a/library-common/src/main/java/com/common/commonlib/db/dao/VideoDao.kt b/library-common/src/main/java/com/common/commonlib/db/dao/VideoDao.kt index bbe47ce..89ad3cd 100644 --- a/library-common/src/main/java/com/common/commonlib/db/dao/VideoDao.kt +++ b/library-common/src/main/java/com/common/commonlib/db/dao/VideoDao.kt @@ -4,7 +4,7 @@ import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.Query -import com.common.commonlib.db.entity.Gas +import androidx.room.Update import com.common.commonlib.db.entity.Video @Dao @@ -23,4 +23,7 @@ interface VideoDao { @Delete suspend fun delete(video: Video) + + @Update + suspend fun update(video: Video) } \ No newline at end of file