Newer
Older
CasicSmartTube / app / src / main / java / com / casic / smarttube / view / AddDeviceActivity.kt
package com.casic.smarttube.view

import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.ViewModelProvider
import cn.bertsir.zbar.QrManager
import com.amap.api.location.AMapLocation
import com.casic.smarttube.R
import com.casic.smarttube.callback.OnImageCompressListener
import com.casic.smarttube.databinding.ActivityAddDeviceBinding
import com.casic.smarttube.extensions.combineImagePath
import com.casic.smarttube.extensions.compressImage
import com.casic.smarttube.extensions.initImmersionBar
import com.casic.smarttube.extensions.isNumber
import com.casic.smarttube.extensions.reformat
import com.casic.smarttube.model.UserDetailModel
import com.casic.smarttube.utils.GlideLoadEngine
import com.casic.smarttube.utils.LoadingDialogHub
import com.casic.smarttube.utils.LocaleConstant
import com.casic.smarttube.utils.LocationHelper
import com.casic.smarttube.utils.QrConfigCreator
import com.casic.smarttube.vm.DeviceViewModel
import com.casic.smarttube.vm.ProjectGroupViewModel
import com.casic.smarttube.vm.UploadImageViewModel
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.pengxh.kt.lite.adapter.EditableImageAdapter
import com.pengxh.kt.lite.base.KotlinBaseActivity
import com.pengxh.kt.lite.extensions.convertColor
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
import com.pengxh.kt.lite.extensions.timestampToCompleteDate
import com.pengxh.kt.lite.utils.LoadState
import com.pengxh.kt.lite.utils.SaveKeyValues
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.widget.TitleBarView
import com.pengxh.kt.lite.widget.dialog.AlertInputDialog
import com.pengxh.kt.lite.widget.dialog.BottomActionSheet
import java.io.File

class AddDeviceActivity : KotlinBaseActivity<ActivityAddDeviceBinding>() {

    private val kTag = "AddDeviceActivity"
    private lateinit var imageAdapter: EditableImageAdapter
    private lateinit var weakReferenceHandler: WeakReferenceHandler
    private lateinit var uploadImageViewModel: UploadImageViewModel
    private lateinit var deviceViewModel: DeviceViewModel
    private lateinit var groupViewModel: ProjectGroupViewModel
    private val context = this
    private val imagePaths: ArrayList<String> = ArrayList() //服务器返回的拍照数据集
    private val realPaths: ArrayList<String> = ArrayList() //真实图片路径
    private val frequency = listOf("1min", "2min", "5min", "10min", "15min", "30min", "60min")
    private var selectedImages = ArrayList<LocalMedia>()
    private val selectLocationLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            if (result.resultCode == RESULT_OK) {
                val data = result.data!!
                binding.longitudeView.text = data.getStringExtra("longitude")
                binding.latitudeView.text = data.getStringExtra("latitude")
            }
        }

    override fun initViewBinding(): ActivityAddDeviceBinding {
        return ActivityAddDeviceBinding.inflate(layoutInflater)
    }

    override fun setupTopBarLayout() {
        binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor)
        binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
            override fun onLeftClick() {
                finish()
            }

            override fun onRightClick() {

            }
        })
    }

    override fun initOnCreate(savedInstanceState: Bundle?) {
        weakReferenceHandler = WeakReferenceHandler(callback)
        uploadImageViewModel = ViewModelProvider(this)[UploadImageViewModel::class.java]
        deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java]
        groupViewModel = ViewModelProvider(this)[ProjectGroupViewModel::class.java]
    }

    override fun observeRequestState() {
        deviceViewModel.loadState.observe(this) {
            when (it) {
                LoadState.Loading -> LoadingDialogHub.show(this, "处理中,请稍后")
                LoadState.Success -> {
                    "添加设备成功".show(this)
                    LoadingDialogHub.dismiss()
                    this.finish()
                }

                LoadState.Fail -> LoadingDialogHub.dismiss()
            }
        }
    }

    override fun initEvent() {
        val manager = QrManager.getInstance().init(QrConfigCreator.create(this))
        binding.scannerView.setOnClickListener {
            manager.startScan(this) {
                if (it.content.isNumber()) {
                    binding.deviceCodeView.setText(it.content)
                } else {
                    "设备编号错误,请检查标签".show(context)
                }
            }
        }

        binding.ownerShipView.setOnClickListener {
            groupViewModel.obtainGroupList()
        }
        groupViewModel.groupListModel.observe(this) {
            val groups = ArrayList<String>()
            if (it.code == 200) {
                if (it.data.isEmpty()) {
                    groups.add("自定义")
                } else {
                    it.data.forEach { id ->
                        groups.add(id)
                    }
                    groups.add("自定义")
                }
            } else {
                groups.add("自定义")
            }
            if (groups.isNotEmpty()) {
                BottomActionSheet.Builder().setContext(this).setItemTextColor(Color.BLUE)
                    .setActionItemTitle(groups)
                    .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener {
                        override fun onActionItemClick(position: Int) {
                            if (groups[position] == "自定义") {
                                AlertInputDialog.Builder().setContext(context).setTitle("提示")
                                    .setHintMessage("请输入该设备所属项目名,如:项目203")
                                    .setNegativeButton("取消").setPositiveButton("确定")
                                    .setOnDialogButtonClickListener(object :
                                        AlertInputDialog.OnDialogButtonClickListener {
                                        override fun onCancelClick() {

                                        }

                                        override fun onConfirmClick(value: String) {
                                            binding.ownerShipView.text = value
                                        }
                                    }).build().show()
                            } else {
                                binding.ownerShipView.text = groups[position]
                            }
                        }
                    }).build().show()
            }
        }

        //默认频率1min
        binding.collectIntervalView.text = frequency[0]
        binding.collectIntervalView.setOnClickListener {
            BottomActionSheet.Builder().setContext(this).setItemTextColor(Color.BLUE)
                .setActionItemTitle(frequency)
                .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener {
                    override fun onActionItemClick(position: Int) {
                        binding.collectIntervalView.text = frequency[position]
                    }
                }).build().show()
        }


        binding.locationImageView.setOnClickListener {
            BottomActionSheet.Builder().setContext(context).setItemTextColor(Color.BLUE)
                .setActionItemTitle(arrayListOf("自动定位", "手动选点"))
                .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener {
                    override fun onActionItemClick(position: Int) {
                        when (position) {
                            0 -> {
                                LoadingDialogHub.show(this@AddDeviceActivity, "定位中,请稍后...")
                                LocationHelper.obtainCurrentLocation(context,
                                    object : LocationHelper.ILocationListener {
                                        override fun onAMapLocationGet(aMapLocation: AMapLocation?) {
                                            LoadingDialogHub.dismiss()
                                            if (aMapLocation == null) {
                                                binding.longitudeView.text = "定位失败"
                                                binding.latitudeView.text = "定位失败"

                                                binding.longitudeView.setTextColor(
                                                    R.color.redTextColor.convertColor(context)
                                                )
                                                binding.latitudeView.setTextColor(
                                                    R.color.redTextColor.convertColor(context)
                                                )
                                            } else {
                                                binding.longitudeView.text =
                                                    aMapLocation.longitude.toString()
                                                binding.latitudeView.text =
                                                    aMapLocation.latitude.toString()

                                                binding.longitudeView.setTextColor(
                                                    R.color.mainTextColor.convertColor(context)
                                                )
                                                binding.latitudeView.setTextColor(
                                                    R.color.mainTextColor.convertColor(context)
                                                )
                                            }
                                        }
                                    })
                            }

                            1 -> selectLocationLauncher.launch(
                                Intent(context, SelectLocationActivity::class.java)
                            )
                        }
                    }
                }).build().show()
        }

//        imageAdapter = EditableImageAdapter(this, 3, 13f)
        binding.addImageRecyclerView.adapter = imageAdapter
        imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
            override fun onAddImageClick() {
                selectPicture()
            }

            override fun onItemClick(position: Int) {
                if (realPaths[position].isEmpty()) {
                    "图片加载失败,无法查看大图".show(context)
                } else {
                    navigatePageTo<BigImageActivity>(position, realPaths)
                }
            }

            override fun onItemLongClick(view: View?, position: Int) {
                imagePaths.removeAt(position)
//                imageAdapter.deleteImage(position)
            }
        })

        uploadImageViewModel.resultModel.observe(this) {
            if (it.code == 200) {
                if (imageAdapter.itemCount == selectedImages.size) {
                    LoadingDialogHub.dismiss()
                }
                if (imageAdapter.itemCount <= 3) {
                    val url = it.data.toString()
                    if (url.isNotBlank()) {
                        imagePaths.add(url)
                        realPaths.add(url.combineImagePath())
                    }
//                    imageAdapter.setupImage(realPaths)
                } else {
                    "最多只能上传3张图片".show(this)
                }
            }
        }

        binding.sceneEditView.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }

            override fun afterTextChanged(s: Editable?) {
                val text = s.toString().trim()
                binding.inputLengthView.text = String.format("${text.length}/100")
                if (text.length > 100) {
                    binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context))
                    "现场情况字符不能超过100个字符".show(context)
                } else {
                    binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context))
                }
            }
        })

        binding.addDeviceTimeView.text = System.currentTimeMillis().timestampToCompleteDate()

        binding.submitButton.setOnClickListener {
            val deviceCode = binding.deviceCodeView.text.toString().trim()
            if (deviceCode.isBlank()) {
                "请输入设备编号".show(context)
                return@setOnClickListener
            }
            val ownerShip = binding.ownerShipView.text.toString().trim()
            if (ownerShip.isBlank()) {
                "请输入设备所属项目".show(context)
                return@setOnClickListener
            }
            val longitude = binding.longitudeView.text.toString().trim()
            val latitude = binding.latitudeView.text.toString().trim()
            if (longitude.isBlank() || latitude.isBlank()) {
                "请先获取当前经纬度".show(context)
                return@setOnClickListener
            }
            val userDetailJson =
                SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_MODEL, "") as String
            if (userDetailJson.isNotBlank()) {
                val userData = Gson().fromJson<UserDetailModel.Data>(
                    userDetailJson, object : TypeToken<UserDetailModel.Data>() {}.type
                )
                deviceViewModel.addDevice(
                    deviceCode,
                    binding.deviceNameView.text.toString(),
                    ownerShip,
                    binding.collectIntervalView.text.toString(),
                    longitude,
                    latitude,
                    imagePaths.reformat(),
                    binding.sceneEditView.text.toString().trim(),
                    binding.addDeviceTimeView.text.toString(),
                    userData.id.toString(),
                    userData.deptId
                )
            }
        }
    }

    private fun selectPicture() {
        BottomActionSheet.Builder().setContext(this).setItemTextColor(Color.BLUE)
            .setActionItemTitle(listOf("拍照", "相册"))
            .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener {
                override fun onActionItemClick(position: Int) {
                    when (position) {
                        0 -> {
                            PictureSelector.create(context).openCamera(SelectMimeType.ofImage())
                                .forResult(object : OnResultCallbackListener<LocalMedia> {
                                    override fun onResult(result: ArrayList<LocalMedia>?) {
                                        if (result == null) {
                                            "拍照保存失败,请重试".show(context)
                                            return
                                        }
                                        LoadingDialogHub.show(
                                            this@AddDeviceActivity, "图片上传中,请稍后..."
                                        )
                                        selectedImages = result
                                        analyticalSelectResults(result[0])
                                    }

                                    override fun onCancel() {

                                    }
                                })
                        }

                        1 -> {
                            PictureSelector.create(context).openGallery(SelectMimeType.ofImage())
                                .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100)
                                .setMaxSelectNum(3).isDisplayCamera(false)
                                .setImageEngine(GlideLoadEngine.instance)
                                .forResult(object : OnResultCallbackListener<LocalMedia> {
                                    override fun onResult(result: ArrayList<LocalMedia>?) {
                                        if (result == null) {
                                            "选择照片失败,请重试".show(context)
                                            return
                                        }
                                        LoadingDialogHub.show(
                                            this@AddDeviceActivity, "图片上传中,请稍后..."
                                        )
                                        selectedImages = result
                                        // 线程控制图片压缩上传过程,防止速度过快导致压缩失败
                                        val sum = (result.size * 1000).toLong()
                                        object : CountDownTimer(sum, 1000) {
                                            override fun onTick(millisUntilFinished: Long) {
                                                val i = millisUntilFinished / 1000
                                                val message = weakReferenceHandler.obtainMessage()
                                                message.obj = result[i.toInt()]
                                                message.what = 2022062501
                                                weakReferenceHandler.handleMessage(message)
                                            }

                                            override fun onFinish() {

                                            }
                                        }.start()
                                    }

                                    override fun onCancel() {

                                    }
                                })
                        }
                    }
                }
            }).build().show()
    }

    private val callback = Handler.Callback {
        if (it.what == 2022062501) {
            analyticalSelectResults(it.obj as LocalMedia)
        }
        true
    }

    private fun analyticalSelectResults(result: LocalMedia) {
        result.realPath.compressImage(this, object : OnImageCompressListener {
            override fun onSuccess(file: File) {
                Log.d(kTag, "onSuccess: " + file.absolutePath)
                //上传图片
                uploadImageViewModel.uploadImage(file)
            }

            override fun onError(e: Throwable) {
                e.printStackTrace()
            }
        })
    }
}