package com.casic.br.view import android.util.Log import android.view.KeyEvent import androidx.lifecycle.ViewModelProvider import com.amap.api.location.AMapLocation import com.casic.br.R import com.casic.br.base.BaseApplication import com.casic.br.extensions.initLayoutImmersionBar import com.casic.br.utils.DeserializeModel import com.casic.br.utils.LoadingDialogHub import com.casic.br.utils.LocationHelper import com.casic.br.vm.DeviceViewModel import com.casic.br.widgets.WaterRippleView import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.Constant import com.pengxh.kt.lite.vm.LoadState import com.tuya.smart.android.ble.api.LeScanSetting import com.tuya.smart.android.ble.api.ScanDeviceBean import com.tuya.smart.android.ble.api.ScanType import com.tuya.smart.android.ble.api.TyBleScanResponse import com.tuya.smart.home.sdk.TuyaHomeSdk import com.tuya.smart.home.sdk.bean.ConfigProductInfoBean import com.tuya.smart.sdk.api.IMultiModeActivatorListener import com.tuya.smart.sdk.api.ITuyaActivatorGetToken import com.tuya.smart.sdk.api.ITuyaDataCallback import com.tuya.smart.sdk.bean.DeviceBean import com.tuya.smart.sdk.bean.MultiModeActivatorBean import kotlinx.android.synthetic.main.activity_scan_bluetooth.* import kotlinx.android.synthetic.main.include_base_title.* import java.util.* import java.util.concurrent.ExecutorService import java.util.concurrent.Executors class ScanBluetoothActivity : KotlinBaseActivity() { private val kTag = "ScanBluetoothActivity" private val context = this@ScanBluetoothActivity private var isRunning = true private lateinit var singleThreadExecutor: ExecutorService private lateinit var params: ArrayList<String> private lateinit var deviceViewModel: DeviceViewModel private var deviceBean: ScanDeviceBean? = null override fun initLayoutView(): Int = R.layout.activity_scan_bluetooth override fun setupTopBarLayout() { ImmersionBar.with(this).statusBarDarkFont(true).init() initLayoutImmersionBar(rootView) leftBackView.setOnClickListener { finish() } titleView.text = "搜索蓝牙设备" } override fun initData() { //只有一个核心线程,当被占用时,其他的任务需要进入队列等待 singleThreadExecutor = Executors.newSingleThreadExecutor() waterRippleView.setOnAnimationStartListener(object : WaterRippleView.OnAnimationStartListener { override fun onStart(view: WaterRippleView?) { view?.start() //开启线程搜索设备 Log.d(kTag, "onStart: 开始线程") singleThreadExecutor.execute(searchRunnable) isRunning = true } }) params = intent.getStringArrayListExtra(Constant.INTENT_PARAM)!! deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] val scanSetting = LeScanSetting.Builder().apply { setTimeout(60000) addScanType(ScanType.SINGLE) }.build() TuyaHomeSdk.getBleOperator().startLeScan(scanSetting, object : TyBleScanResponse { override fun onResult(bean: ScanDeviceBean?) { if (bean == null) { Log.e(kTag, "onResult: 无法扫描到涂鸦蓝牙模组") return } deviceBean = bean TuyaHomeSdk.getActivatorInstance().getActivatorDeviceInfo( deviceBean!!.productId, deviceBean!!.uuid, deviceBean!!.mac, object : ITuyaDataCallback<ConfigProductInfoBean> { override fun onSuccess(result: ConfigProductInfoBean?) { if (result == null) { Log.e(kTag, "onResult: 无法获取涂鸦设备信息") return } tipsView.text = "已搜索到蓝牙设备,基本信息如下" deviceAddressView.text = String.format("设备地址:${deviceBean!!.address}") deviceNameView.text = String.format("产品名称:${result.name}") } override fun onError(errorCode: String?, errorMessage: String?) { Log.e(kTag, "startLeScan onError: $errorMessage") } }) } }) } private val searchRunnable = Runnable { while (true) { try { if (!isRunning) { Log.d(kTag, "run: 设备搜索线程休眠中...") Thread.sleep(Long.MAX_VALUE) } } catch (e: Exception) { e.printStackTrace() } Log.d(kTag, "run: 设备搜索线程运行中...") try { //搜索设备 Thread.sleep(1000) } catch (e: InterruptedException) { e.printStackTrace() } } } override fun onPause() { super.onPause() isRunning = false waterRippleView.stop() TuyaHomeSdk.getBleOperator().stopLeScan() } override fun initEvent() { nextStepButton.setOnClickListener { val userModel = DeserializeModel.getUserModel()!! val homeId = DeserializeModel.getHomeId() Log.d(kTag, "homeId: $homeId") if (deviceBean == null) { "正在扫描设备,请稍后".show(this) return@setOnClickListener } LoadingDialogHub.show(this, "设备配网中,请稍后") LocationHelper.obtainCurrentLocation(this, object : LocationHelper.ILocationListener { override fun onAMapLocationGet(aMapLocation: AMapLocation?) { if (aMapLocation == null) { "信号弱,添加设备失败".show(BaseApplication.obtainInstance()) LoadingDialogHub.dismiss() return } TuyaHomeSdk.getActivatorInstance() .getActivatorToken(homeId, object : ITuyaActivatorGetToken { override fun onSuccess(token: String?) { val multiModeActivatorBean = MultiModeActivatorBean() multiModeActivatorBean.homeId = homeId multiModeActivatorBean.deviceType = deviceBean!!.deviceType multiModeActivatorBean.uuid = deviceBean!!.uuid multiModeActivatorBean.address = deviceBean!!.address multiModeActivatorBean.mac = deviceBean!!.mac multiModeActivatorBean.ssid = params[0] multiModeActivatorBean.pwd = params[1] multiModeActivatorBean.token = token multiModeActivatorBean.timeout = 120000 // 开始配网 TuyaHomeSdk.getActivator().newMultiModeActivator().startActivator( multiModeActivatorBean, object : IMultiModeActivatorListener { override fun onSuccess(deviceBean: DeviceBean?) { //将绑定的设备存入自己的数据库 deviceViewModel.addDevice( deviceBean!!, userModel, "1", aMapLocation ) } override fun onFailure( code: Int, msg: String?, handle: Any? ) { Log.d(kTag, "errorMsg: $msg") "添加设备失败".show(context) LoadingDialogHub.dismiss() } }) } override fun onFailure(errorCode: String?, errorMsg: String?) { "获取设备配网Token失败,无法配网".show(context) LoadingDialogHub.dismiss() } }) } }) } } override fun observeRequestState() { deviceViewModel.loadState.observe(this, { when (it) { LoadState.Success -> { LoadingDialogHub.dismiss() navigatePageTo<AddDeviceResultActivity>() } else -> { "添加失败,请重新绑定".show(this) LoadingDialogHub.dismiss() } } }) } override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { if (keyCode == KeyEvent.KEYCODE_BACK) { if (deviceBean == null) { return super.onKeyDown(keyCode, event) } TuyaHomeSdk.getActivator().newMultiModeActivator().stopActivator(deviceBean!!.uuid) } return super.onKeyDown(keyCode, event) } }