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() } }) } }