SwipeActivity.kt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. package com.example.chemical.ui.login
  2. import android.content.IntentFilter
  3. import android.hardware.usb.UsbManager
  4. import android.os.Bundle
  5. import android.os.Handler
  6. import android.os.Looper
  7. import android.view.KeyEvent
  8. import android.view.LayoutInflater
  9. import android.view.MotionEvent
  10. import android.view.View
  11. import android.widget.TextView
  12. import com.blankj.utilcode.util.AppUtils
  13. import com.bumptech.glide.Glide
  14. import com.bumptech.glide.load.engine.DiskCacheStrategy
  15. import com.bumptech.glide.request.RequestOptions
  16. import com.example.chemical.ChemicalApp
  17. import com.example.chemical.R
  18. import com.example.chemical.databinding.ActivitySwipeBinding
  19. import com.example.chemical.receiver.OnSerialScanListener
  20. import com.example.chemical.receiver.PortScanHelper
  21. import com.example.chemical.receiver.UsbReceiver
  22. import com.example.chemical.ui.MainActivity
  23. import com.example.chemical.ui.common.BaseCountDownActivity
  24. import com.example.chemical.utils.MediaPlayerHelper
  25. import com.example.chemical.utils.UiManager
  26. import com.example.chemical.weidith.AuthenticationDialog
  27. import com.example.chemical.weidith.CustomDialog
  28. import com.rc.core.log.RcLog
  29. import com.rc.httpcore.HttpClient
  30. import com.rc.httpcore.HttpConfig
  31. import com.rc.httpcore.client.ApiRepository
  32. import com.rc.httpcore.exception.NetException
  33. import org.greenrobot.eventbus.EventBus
  34. import org.greenrobot.eventbus.Subscribe
  35. import org.greenrobot.eventbus.ThreadMode
  36. import retrofit2.HttpException
  37. import java.net.ConnectException
  38. import java.net.SocketTimeoutException
  39. /**
  40. * 刷卡登录
  41. */
  42. class SwipeActivity : BaseCountDownActivity<ActivitySwipeBinding>() {
  43. private var mUsbReceiver: UsbReceiver? = null // 刷卡广播注册
  44. private var mHandleScanEvent = false //当前是否已经获取过 usb返回的参数
  45. override fun createViewBinding() = ActivitySwipeBinding.inflate(LayoutInflater.from(this))
  46. override fun initViews(savedInstanceState: Bundle?) {
  47. super.initViews(savedInstanceState)
  48. MediaPlayerHelper.playRawMp3(this, R.raw.login_shua_ka)
  49. //注册广播
  50. EventBus.getDefault().register(this)
  51. viewBinding.tvReturn.text = "返回${ChemicalApp.confs!!.backTime}s"
  52. viewBinding.tvReturn.setOnClickListener {
  53. UiManager.switcherCashier(this, MainActivity::class.java)
  54. }
  55. val stringExtra = intent.getStringExtra("mtypes")
  56. when (stringExtra) {
  57. "1" -> {
  58. viewBinding.linType.visibility = View.GONE
  59. }
  60. "6" -> {
  61. viewBinding.tvFace.visibility = View.GONE
  62. }
  63. "4" -> {
  64. viewBinding.tvWx.visibility = View.GONE
  65. }
  66. }
  67. viewBinding.deptName.text = "${ChemicalApp.confs!!.deptName}-${ChemicalApp.confs!!.roomNum}"
  68. Glide.with(this)
  69. .load("${HttpConfig.API_BASE_IMG_URL}${ChemicalApp.confs!!.circularLogo}")
  70. .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.AUTOMATIC))
  71. .into(viewBinding.image)
  72. val map = mutableMapOf<String, String>()
  73. if (stringExtra != null) {
  74. map["mtypes"] = stringExtra
  75. }
  76. try {
  77. val face = intent.getStringExtra("faceList")
  78. if (face != null) {
  79. map["faceList"] = face
  80. }
  81. } catch (e: Exception) {
  82. }
  83. viewBinding.tvFace.setOnClickListener {
  84. UiManager.switcher(this, map, FacialLoginActivity::class.java)
  85. finish()
  86. }
  87. viewBinding.tvWx.setOnClickListener {
  88. if (stringExtra != null) {
  89. map["mtypes"] = stringExtra
  90. }
  91. UiManager.switcher(this, map, ScanLoginActivity::class.java)
  92. finish()
  93. }
  94. //TODO 测试通道
  95. if (AppUtils.isAppDebug()) {
  96. handleScanEvent("0459035363")
  97. }
  98. }
  99. override fun onResume() {
  100. super.onResume()
  101. mPortScanHelper.onResume()
  102. registerUsbBroadcast()
  103. }
  104. private val mPortScanHelper by lazy {
  105. PortScanHelper(this, object : OnSerialScanListener {
  106. override fun dispatchScanEvent(type: OnSerialScanListener.ScanType, content: String) {
  107. if (!mHandleScanEvent) {
  108. if (content.isNotBlank()) {
  109. mHandleScanEvent = true
  110. handleScanEvent(content)
  111. }
  112. }
  113. }
  114. })
  115. }
  116. //刷卡usb链接
  117. private fun registerUsbBroadcast() {
  118. if (null == mUsbReceiver) {
  119. val filter = IntentFilter().apply {
  120. addAction(UsbReceiver.ACTION_USB_PERMISSION)
  121. addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
  122. addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
  123. addAction(UsbReceiver.ACTION_USB_STATE) // usb连接状态广播
  124. }
  125. mUsbReceiver = UsbReceiver()
  126. registerReceiver(mUsbReceiver, filter)
  127. }
  128. }
  129. //调用刷卡信息
  130. private fun handleScanEvent(cont: String) {
  131. showLoading("登录中...")
  132. HttpClient.token = null
  133. val disposable = ApiRepository.cardNum(cont)
  134. .subscribe({ data ->
  135. ChemicalApp.userData = data
  136. authenticationInfo(data.userId, ChemicalApp.subjectId!!)
  137. }, { throwable ->
  138. dismissLoading()
  139. throwableView(throwable)
  140. mHandleScanEvent = false
  141. })
  142. addDisposable(disposable)
  143. }
  144. //验证当前人员身份
  145. private fun authenticationInfo(userId: String, subId: String) {
  146. showLoading("验证中...")
  147. val disposable = ApiRepository.userCardValidation(userId, subId)
  148. .subscribe({ data ->
  149. dismissLoading()
  150. val allFalse = with(data) {
  151. cabinetAdmin == false &&
  152. belongUser == false &&
  153. toipcUser == false &&
  154. safeUser == false &&
  155. collegeAdmin == false &&
  156. schoolLevelAdmin == false &&
  157. adminUser == false
  158. }
  159. ChemicalApp.responsibles = false
  160. ChemicalApp.administrators = false
  161. if (allFalse) {
  162. HttpClient.token = null
  163. ChemicalApp.userData = null
  164. customDialogView(2, "当前身份不符合")
  165. mHandleScanEvent = false
  166. } else {
  167. //校级管理员 schoolLevelAdmin
  168. //院级管理员 collegeAdmin
  169. //实验室负责人 adminUser
  170. //安全负责人 safeUser
  171. //柜锁管理员 cabinetAdmin
  172. //是否化学品归属人 belongUser
  173. //是否化学品归属课题组下成员 toipcUser
  174. if (data.schoolLevelAdmin == true || data.collegeAdmin == true) {
  175. //院级管理员 or 校级管理员
  176. ChemicalApp.administrators = true
  177. authenticationDialog(data.faceImg, data.userName)
  178. } else if (data.adminUser == true || data.safeUser == true || data.cabinetAdmin == true) {
  179. //实验室负责人 or 安全负责人 or 柜锁管理员
  180. ChemicalApp.responsibles = true
  181. authenticationDialog(data.faceImg, data.userName)
  182. } else if (data.belongUser == true || data.toipcUser == true) { //当前身份 归属人or课题组
  183. ChemicalApp.responsibles = false
  184. ChemicalApp.administrators = false
  185. authenticationDialog(data.faceImg, data.userName)
  186. } else {
  187. HttpClient.token = null
  188. ChemicalApp.userData = null
  189. customDialogView(2, "当前身份不符合")
  190. mHandleScanEvent = false
  191. }
  192. }
  193. }, { throwable ->
  194. dismissLoading()
  195. throwableView(throwable)
  196. HttpClient.token = null
  197. ChemicalApp.userData = null
  198. mHandleScanEvent = false
  199. })
  200. addDisposable(disposable)
  201. }
  202. //获取刷卡信息
  203. override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
  204. mPortScanHelper.dispatchKeyEvent(event)
  205. return super.dispatchKeyEvent(event)
  206. }
  207. //停止 销毁广播传递
  208. override fun onPause() {
  209. mPortScanHelper.onPause()
  210. super.onPause()
  211. }
  212. override fun onDestroy() {
  213. super.onDestroy()
  214. mPortScanHelper.onPause()
  215. // 移除回调,以防止内存泄漏
  216. try {
  217. handlerBack.removeCallbacks(countdownRunnable)
  218. } catch (e: Exception) {
  219. }
  220. unregisterReceiver(mUsbReceiver)
  221. // 停止定时更新
  222. EventBus.getDefault().unregister(this) //关闭广播
  223. }
  224. //必须写这个方法 防止注册失败
  225. @Subscribe(threadMode = ThreadMode.MAIN)
  226. fun onUpdateEventEvent(event: KeyEvent) {
  227. }
  228. override fun onBackPressed() {
  229. super.onBackPressed()
  230. UiManager.switcherCashier(this, MainActivity::class.java)
  231. }
  232. private val handlerBack = Handler(Looper.getMainLooper())
  233. private var timeLeftInSeconds = 5
  234. private var mTvView: TextView? = null
  235. private var mDialogsAut: AuthenticationDialog? = null
  236. //身份认证成功
  237. private fun authenticationDialog(faceImg: String?, userName: String) {
  238. MediaPlayerHelper.playRawMp3(this, R.raw.login_ren_zheng_tong_hua)
  239. mDialogsAut = AuthenticationDialog(
  240. this,
  241. faceImg,
  242. ChemicalApp.confs!!.subName,
  243. ChemicalApp.confs!!.deptName,
  244. "${ChemicalApp.confs!!.buildName}${ChemicalApp.confs!!.floorName}",
  245. userName, object : AuthenticationDialog.IClickLit {
  246. override fun onUpView(tvView: TextView) {
  247. mTvView = tvView
  248. }
  249. })
  250. mDialogsAut!!.show()
  251. // 开始倒计时
  252. handlerBack.post(countdownRunnable)
  253. // 获取对话框的 Window 对象
  254. mDialogsAut!!.window?.decorView?.setOnTouchListener { _, event ->
  255. // 判断是否点击了对话框外部空白区域
  256. if (event.action == MotionEvent.ACTION_DOWN) {
  257. val x = event.x
  258. val y = event.y
  259. val dialogView = mDialogsAut!!.window?.decorView
  260. if (dialogView != null && (x < 0 || x > dialogView.width || y < 0 || y > dialogView.height)) {
  261. // 在此处执行点击对话框外部空白区域时的操作
  262. // 例如关闭对话框
  263. // 移除回调,以防止内存泄漏
  264. mDialogsAut!!.dismiss()
  265. finish()
  266. return@setOnTouchListener true
  267. }
  268. }
  269. return@setOnTouchListener false
  270. }
  271. }
  272. private val countdownRunnable = object : Runnable {
  273. override fun run() {
  274. if (timeLeftInSeconds > 0) {
  275. mTvView!!.text = "${timeLeftInSeconds}秒后自动返回首页"
  276. timeLeftInSeconds--
  277. handlerBack.postDelayed(this, 1000)
  278. } else {
  279. mDialogsAut!!.dismiss()
  280. finish()
  281. }
  282. }
  283. }
  284. /**
  285. * 0 没有图标 1 绿色 2红色
  286. * 失败或者成功的弹框
  287. */
  288. private fun customDialogView(types: Int, msg: String) {
  289. if (!this.isFinishing && !this.isDestroyed) {
  290. val customDialog = CustomDialog(this, types, msg)
  291. customDialog.show()
  292. }
  293. }
  294. /**
  295. * 异常处理
  296. */
  297. private fun throwableView(throwable: Throwable) {
  298. when (throwable) {
  299. is NetException -> {
  300. if (throwable.message.isNullOrEmpty()) {
  301. "接口请求失败(${throwable.code})"
  302. } else {
  303. throwable.message!!
  304. }
  305. }
  306. is SocketTimeoutException -> "请求超时,请稍后重试"
  307. is ConnectException -> "无法连接服务器,请检查网络"
  308. is HttpException -> "服务器繁忙,请稍后重试"
  309. else -> null
  310. }?.let { customDialogView(2, "$it") }
  311. }
  312. }