人脸识别支付流程
This commit is contained in:
@@ -4,8 +4,10 @@ import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.Display
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.widget.TextView
|
||||
@@ -23,6 +25,12 @@ import timber.log.Timber
|
||||
|
||||
|
||||
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
|
||||
val displays: Array<Display> by lazy {
|
||||
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||
displayManager.displays
|
||||
}
|
||||
|
||||
protected lateinit var binding: VB
|
||||
protected lateinit var context: Context
|
||||
private var mDialogWaiting: CustomDialog? = null
|
||||
|
||||
@@ -8,9 +8,11 @@ import com.sw.dualscreen.activity.fragment.pay.CashPayFragment
|
||||
import com.sw.dualscreen.activity.fragment.pay.FacePayFragment
|
||||
import com.sw.dualscreen.activity.fragment.pay.NumberPayFragment
|
||||
import com.sw.dualscreen.activity.fragment.pay.PayResultFragment
|
||||
import com.sw.dualscreen.activity.fragment.pay.QrCodePayFragment
|
||||
import com.sw.dualscreen.activity.fragment.pay.ScanQrCodePayFragment
|
||||
import com.sw.dualscreen.databinding.ActivityPayBinding
|
||||
import com.sw.dualscreen.model.response.FoodInfo
|
||||
import com.sw.dualscreen.presentation.pay.FacePayPresentation
|
||||
import com.sw.dualscreen.presentation.pay.ScanQrCodePayPresentation
|
||||
import com.sw.dualscreen.viewmodel.BaseViewModel
|
||||
import com.sw.dualscreen.viewmodel.UserViewModel
|
||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||
@@ -40,10 +42,10 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
|
||||
|
||||
var foodInfo: FoodInfo? = null
|
||||
|
||||
private var qrCodePayFragment: QrCodePayFragment? = null
|
||||
private var qrCodePayFragment: ScanQrCodePayFragment? = null
|
||||
private var cashPayFragment: CashPayFragment? = null
|
||||
private var numberPayFragment: NumberPayFragment? = null
|
||||
private var facePayFragment: FacePayFragment? = null
|
||||
var facePayFragment: FacePayFragment? = null
|
||||
private var payResultFragment: PayResultFragment? = null
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@@ -53,33 +55,48 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
|
||||
binding.tvFoodName.text = foodInfo?.foodName
|
||||
binding.include.ivPageBack.setOnClickListener { finish() }
|
||||
binding.include.tvPageTitle.text = "下单结算"
|
||||
val payQrCodeClickListener = View.OnClickListener {
|
||||
if (qrCodePayFragment == null) {
|
||||
qrCodePayFragment = QrCodePayFragment()
|
||||
binding.btnPayQrCode.setOnClickListener {
|
||||
if (binding.btnPayQrCode.isChecked) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
addFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE)
|
||||
switchButton(true, false, false, false)
|
||||
showScanQrCodePay()
|
||||
}
|
||||
binding.btnPayQrCode.setOnClickListener(payQrCodeClickListener)
|
||||
binding.btnPayCash.setOnClickListener {
|
||||
if (binding.btnPayCash.isChecked) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (cashPayFragment == null) {
|
||||
cashPayFragment = CashPayFragment()
|
||||
}
|
||||
addFragment(cashPayFragment!!, TAG_PAY_CASH)
|
||||
showFragment(cashPayFragment!!, TAG_PAY_CASH)
|
||||
switchButton(false, true, false, false)
|
||||
}
|
||||
binding.btnPayNumber.setOnClickListener {
|
||||
if (binding.btnPayNumber.isChecked) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (numberPayFragment == null) {
|
||||
numberPayFragment = NumberPayFragment()
|
||||
}
|
||||
addFragment(numberPayFragment!!, TAG_PAY_NUMBER)
|
||||
showFragment(numberPayFragment!!, TAG_PAY_NUMBER)
|
||||
switchButton(false, false, true, false)
|
||||
}
|
||||
binding.btnPayFace.setOnClickListener {
|
||||
if (binding.btnPayFace.isChecked) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
showFacePay()
|
||||
}
|
||||
|
||||
payQrCodeClickListener.onClick(binding.btnPayQrCode)
|
||||
showScanQrCodePay()
|
||||
}
|
||||
|
||||
private fun showScanQrCodePay() {
|
||||
if (qrCodePayFragment == null) {
|
||||
qrCodePayFragment = ScanQrCodePayFragment()
|
||||
}
|
||||
showFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE)
|
||||
switchButton(true, false, false, false)
|
||||
}
|
||||
|
||||
private fun switchButton(vararg arr: Boolean) {
|
||||
@@ -93,38 +110,49 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
|
||||
if (facePayFragment == null) {
|
||||
facePayFragment = FacePayFragment()
|
||||
}
|
||||
addFragment(facePayFragment!!, TAG_PAY_FACE)
|
||||
showFragment(facePayFragment!!, TAG_PAY_FACE)
|
||||
switchButton(false, false, false, true)
|
||||
}
|
||||
|
||||
private fun addFragment(currentFragment: Fragment, tag: String) {
|
||||
private fun showFragment(fragment: Fragment, tag: String) {
|
||||
runCatching {
|
||||
supportFragmentManager.beginTransaction().apply {
|
||||
val existFragment = supportFragmentManager.findFragmentByTag(tag)
|
||||
if (existFragment == null) {
|
||||
add(R.id.fragmentContainerView, currentFragment, tag)
|
||||
}
|
||||
val fragments = supportFragmentManager.fragments
|
||||
fragments.forEach {
|
||||
it?.let { fragment ->
|
||||
if (fragment != currentFragment) {
|
||||
hide(fragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
show(currentFragment)
|
||||
commitAllowingStateLoss()
|
||||
replace(R.id.fragmentContainerView, fragment)
|
||||
commitNowAllowingStateLoss()
|
||||
}
|
||||
}.onFailure {
|
||||
it.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
// private fun showFragment(currentFragment: Fragment, tag: String) {
|
||||
// runCatching {
|
||||
// supportFragmentManager.beginTransaction().apply {
|
||||
// val existFragment = supportFragmentManager.findFragmentByTag(tag)
|
||||
// if (existFragment == null) {
|
||||
// add(R.id.fragmentContainerView, currentFragment, tag)
|
||||
// }
|
||||
// val fragments = supportFragmentManager.fragments
|
||||
// fragments.forEach {
|
||||
// it?.let { fragment ->
|
||||
// if (fragment != currentFragment) {
|
||||
// hide(fragment)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// show(currentFragment)
|
||||
// commitAllowingStateLoss()
|
||||
// }
|
||||
// }.onFailure {
|
||||
// it.printStackTrace()
|
||||
// }
|
||||
// }
|
||||
|
||||
fun showPayResult() {
|
||||
if (payResultFragment == null) {
|
||||
payResultFragment = PayResultFragment()
|
||||
}
|
||||
addFragment(payResultFragment!!, TAG_PAY_RESULT)
|
||||
showFragment(payResultFragment!!, TAG_PAY_RESULT)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
@@ -134,5 +162,22 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
|
||||
facePayFragment?.presentation?.dismiss()
|
||||
super.onDestroy()
|
||||
}
|
||||
private var scanQrCodePayPresentation: ScanQrCodePayPresentation?=null
|
||||
fun paySuccess() {
|
||||
showFragment(PayResultFragment(),"")
|
||||
if (displays.size > 1) {
|
||||
scanQrCodePayPresentation = ScanQrCodePayPresentation(
|
||||
activity = this,
|
||||
display = displays[1],
|
||||
type = 2
|
||||
) {
|
||||
scanQrCodePayPresentation?.dismiss()
|
||||
}.also {
|
||||
// it.foodName = foodName
|
||||
// it.payAmount = payAmount
|
||||
}
|
||||
scanQrCodePayPresentation?.show()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.sw.dualscreen.activity.fragment.pay
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import com.sw.dualscreen.activity.PayActivity
|
||||
import com.sw.dualscreen.activity.fragment.BaseFragment
|
||||
import com.sw.dualscreen.databinding.FragmentFacePayBinding
|
||||
import com.sw.dualscreen.presentation.pay.CashPayPresentation
|
||||
import com.sw.dualscreen.presentation.pay.FacePayPresentation
|
||||
|
||||
class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
|
||||
@@ -37,6 +37,10 @@ class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
|
||||
showSubScreen()
|
||||
}
|
||||
|
||||
fun loadBitmap(frame: Bitmap) {
|
||||
binding.ivFaceImage.setImageBitmap(frame)
|
||||
}
|
||||
|
||||
private fun showSubScreen() {
|
||||
// 查找副屏(通常索引为1)
|
||||
if (displays.size > 1) {
|
||||
@@ -45,6 +49,7 @@ class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
|
||||
display = displays[1],
|
||||
userViewModel = payActivity!!.userViewModel,
|
||||
recognizeViewModel = payActivity!!.recognizeViewModel,
|
||||
// parentTextureView = binding.parentTextureView,
|
||||
) {
|
||||
presentation?.dismiss()
|
||||
}.also {
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
package com.sw.dualscreen.activity.fragment.pay
|
||||
|
||||
import android.text.Spanned
|
||||
import android.text.SpannedString
|
||||
import android.text.style.AbsoluteSizeSpan
|
||||
import androidx.core.text.buildSpannedString
|
||||
import com.sw.dualscreen.R
|
||||
import com.sw.dualscreen.activity.PayActivity
|
||||
import com.sw.dualscreen.activity.fragment.BaseFragment
|
||||
import com.sw.dualscreen.databinding.FragmentPayResultBinding
|
||||
import com.sw.dualscreen.ext.load
|
||||
|
||||
class PayResultFragment: BaseFragment<FragmentPayResultBinding>() {
|
||||
|
||||
@@ -10,20 +16,25 @@ class PayResultFragment: BaseFragment<FragmentPayResultBinding>() {
|
||||
return FragmentPayResultBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
|
||||
private var payActivity: PayActivity? = null
|
||||
override fun initialize() {
|
||||
payActivity = activity as PayActivity
|
||||
binding.btnBack.setOnClickListener {
|
||||
payActivity?.showFacePay()
|
||||
//payActivity?.showFacePay()
|
||||
}
|
||||
|
||||
binding.ivHeadPic.load(R.mipmap.ic_launcher)
|
||||
binding.tvUserName.text = "张三"
|
||||
binding.tvUserPhone.text = "132****5678"
|
||||
binding.tvUserBalance.text = getBalanceText("0.00")
|
||||
binding.tvPayAmount.text = "收款金额 20.00 元"
|
||||
binding.tvPayInfo.text = "应收 38.00 元,余额扣除 16.80 元"
|
||||
}
|
||||
|
||||
override fun onHiddenChanged(hidden: Boolean) {
|
||||
super.onHiddenChanged(hidden)
|
||||
//显示时重新查询接口
|
||||
if (hidden.not()) {
|
||||
|
||||
private fun getBalanceText(amount: String): SpannedString {
|
||||
return buildSpannedString {
|
||||
append("¥", AbsoluteSizeSpan(20, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(amount, AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-8
@@ -8,22 +8,25 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.sw.dualscreen.R
|
||||
import com.sw.dualscreen.activity.PayActivity
|
||||
import com.sw.dualscreen.activity.fragment.BaseFragment
|
||||
import com.sw.dualscreen.databinding.FragmentQrcodePayBinding
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.presentation.pay.QrCodePayPresentation
|
||||
import com.sw.dualscreen.presentation.pay.ScanQrCodePayPresentation
|
||||
import com.sw.dualscreen.utils.countDownByFlow
|
||||
import kotlinx.coroutines.Job
|
||||
import com.sw.dualscreen.databinding.FragmentScanQrcodePayBinding
|
||||
|
||||
class QrCodePayFragment: BaseFragment<FragmentQrcodePayBinding>() {
|
||||
class ScanQrCodePayFragment: BaseFragment<FragmentScanQrcodePayBinding>() {
|
||||
|
||||
companion object {
|
||||
|
||||
}
|
||||
|
||||
private lateinit var payActivity: PayActivity
|
||||
private var foodName: String? = null
|
||||
private var payAmount: String? = null
|
||||
private var payQrCodePic: Any? = null
|
||||
var presentation: QrCodePayPresentation?=null
|
||||
override fun inflateViewBinding(): FragmentQrcodePayBinding {
|
||||
return FragmentQrcodePayBinding.inflate(layoutInflater)
|
||||
var presentation: ScanQrCodePayPresentation?=null
|
||||
override fun inflateViewBinding(): FragmentScanQrcodePayBinding {
|
||||
return FragmentScanQrcodePayBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
override fun initialize() {
|
||||
@@ -55,7 +58,7 @@ class QrCodePayFragment: BaseFragment<FragmentQrcodePayBinding>() {
|
||||
private fun showSubScreen() {
|
||||
// 查找副屏(通常索引为1)
|
||||
if (displays.size > 1) {
|
||||
presentation = QrCodePayPresentation(activity = payActivity, display = displays[1]) {
|
||||
presentation = ScanQrCodePayPresentation(activity = payActivity, type = 0, display = displays[1]) {
|
||||
presentation?.dismiss()
|
||||
}.also {
|
||||
it.foodName = foodName
|
||||
@@ -83,7 +86,7 @@ class QrCodePayFragment: BaseFragment<FragmentQrcodePayBinding>() {
|
||||
binding.tvPayResult.text = "待支付(${seconds}s)..."
|
||||
},
|
||||
onFinish = {
|
||||
binding.tvPayResult.text = "支付倒计时结束"
|
||||
binding.tvPayResult.text = "待支付"
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class MainScreenPresentation(
|
||||
binding = PresentationMainScreenBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
||||
window?.setBackgroundDrawableResource(android.R.color.transparent)
|
||||
window?.setBackgroundDrawableResource(android.R.color.white)
|
||||
initView()
|
||||
setupArcCamera()
|
||||
registerDataChange()
|
||||
@@ -713,8 +713,10 @@ class MainScreenPresentation(
|
||||
val layoutParams = previewView.layoutParams
|
||||
// layoutParams.width = (608.dp * 1.5).roundToInt()
|
||||
// layoutParams.height = (456.dp * 1.5).roundToInt()
|
||||
layoutParams.width = (600.dp * 1.5).roundToInt()
|
||||
layoutParams.height = (400.dp * 1.5).roundToInt()
|
||||
// layoutParams.width = (600.dp * 1.5).roundToInt()
|
||||
// layoutParams.height = (450.dp * 1.5).roundToInt()
|
||||
layoutParams.width = 1024
|
||||
layoutParams.height = 768
|
||||
previewView.setLayoutParams(layoutParams)
|
||||
faceRectView.setLayoutParams(layoutParams)
|
||||
return layoutParams
|
||||
|
||||
@@ -41,4 +41,9 @@ class CashPayPresentation(
|
||||
append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisplayRemoved() {
|
||||
super.onDisplayRemoved()
|
||||
onDismissListener()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sw.dualscreen.presentation.pay
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Dialog
|
||||
import android.app.Presentation
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
@@ -10,24 +11,26 @@ import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.text.SpannedString
|
||||
import android.text.TextUtils
|
||||
import android.text.style.AbsoluteSizeSpan
|
||||
import android.view.Display
|
||||
import android.view.TextureView
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.text.buildSpannedString
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.arcsoft.face.ErrorInfo
|
||||
import com.sw.dualscreen.GlobalKey
|
||||
import com.sw.dualscreen.R
|
||||
import com.sw.dualscreen.activity.PayActivity
|
||||
import com.sw.dualscreen.databinding.PresentationFacePayBinding
|
||||
import com.sw.dualscreen.ext.dp
|
||||
import com.sw.dualscreen.presentation.MainScreenPresentation
|
||||
import com.sw.dualscreen.utils.SPUtil
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.view.CustomDialog
|
||||
import com.sw.dualscreen.viewmodel.UserViewModel
|
||||
import com.sw.plate.utils.ToastUtils
|
||||
import com.sw.plate.utils.arcface.ConfigUtil
|
||||
@@ -45,13 +48,13 @@ import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration
|
||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class FacePayPresentation(
|
||||
val activity: PayActivity,
|
||||
display: Display,
|
||||
val userViewModel: UserViewModel,
|
||||
val recognizeViewModel: RecognizeViewModel,
|
||||
// val //parentTextureView: TextureView,
|
||||
private val onDismissListener: () -> Unit = {}
|
||||
) : Presentation(activity, display) , ViewTreeObserver.OnGlobalLayoutListener {
|
||||
|
||||
@@ -75,16 +78,20 @@ class FacePayPresentation(
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = PresentationFacePayBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
window?.setBackgroundDrawableResource(R.color.transparent)
|
||||
window?.setBackgroundDrawableResource(android.R.color.white)
|
||||
initView()
|
||||
setupArcCamera()
|
||||
registerDataChange()
|
||||
|
||||
pauseCamera()
|
||||
}
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
|
||||
resumeCamera()
|
||||
binding.root.postDelayed({
|
||||
resumeCamera()
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
var foodName: String? = null
|
||||
@@ -92,6 +99,14 @@ class FacePayPresentation(
|
||||
private fun initView() {
|
||||
binding.tvFoodName.text = foodName
|
||||
binding.tvRealAmount.text = getAmountText(payAmount ?: "")
|
||||
// binding.ivPreviewImage.let {
|
||||
// it.outlineProvider = object : ViewOutlineProvider() {
|
||||
// override fun getOutline(view: View, outline: Outline) {
|
||||
// outline.setRoundRect(0, 0, view.width, view.height, 12f.dp)
|
||||
// }
|
||||
// }
|
||||
// it.clipToOutline = true
|
||||
// }
|
||||
}
|
||||
|
||||
private fun getAmountText(amount: String): SpannedString {
|
||||
@@ -104,6 +119,7 @@ class FacePayPresentation(
|
||||
override fun onGlobalLayout() {
|
||||
Timber.tag(TAG).d("onGlobalLayout")
|
||||
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().removeOnGlobalLayoutListener(this)
|
||||
//parentTextureView.getViewTreeObserver().removeOnGlobalLayoutListener(this)
|
||||
openCamera()
|
||||
}
|
||||
private fun openCamera() {
|
||||
@@ -249,17 +265,16 @@ class FacePayPresentation(
|
||||
val userId = faceEntity.userName
|
||||
if (userId == null ) return@Observer
|
||||
activity.runOnUiThread {
|
||||
ToastUtils.showToast("获取用户id成功")
|
||||
//ToastUtils.showToast("用户人脸识别成功,挑战支付页面")
|
||||
showWaitingDialog("刷脸支付中,请稍后……")
|
||||
binding.root.postDelayed({
|
||||
hideWaitingDialog()
|
||||
activity.paySuccess()
|
||||
binding.root.postDelayed({
|
||||
dismiss()
|
||||
},500)
|
||||
},1500)
|
||||
}
|
||||
// if (currentFood == null) {
|
||||
// //重新识别
|
||||
// activity.runOnUiThread {
|
||||
// ToastUtils.showToast("currentFood == null")
|
||||
// }
|
||||
// //activity.recognizeFood()
|
||||
// //step1FoodRecognizing()
|
||||
// return@Observer
|
||||
// }
|
||||
// userViewModel.getUserNutritionData(
|
||||
// userId = userId,
|
||||
// foodId = currentFood!!.id!!
|
||||
@@ -274,6 +289,7 @@ class FacePayPresentation(
|
||||
private fun initArcView() {
|
||||
//在布局结束后才做初始化操作
|
||||
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().addOnGlobalLayoutListener(this)
|
||||
//parentTextureView.getViewTreeObserver().addOnGlobalLayoutListener(this)
|
||||
recognizeViewModel.getCompareResultList().getValue()
|
||||
}
|
||||
|
||||
@@ -337,8 +353,10 @@ class FacePayPresentation(
|
||||
val layoutParams = previewView.layoutParams
|
||||
// layoutParams.width = (608.dp * 1.5).roundToInt()
|
||||
// layoutParams.height = (456.dp * 1.5).roundToInt()
|
||||
layoutParams.width = (600.dp * 1.5).roundToInt()
|
||||
layoutParams.height = (400.dp * 1.5).roundToInt()
|
||||
// layoutParams.width = (608.dp * 1.5).roundToInt()
|
||||
// layoutParams.height = (456.dp * 1.5).roundToInt()
|
||||
layoutParams.width = 1024
|
||||
layoutParams.height = 768
|
||||
previewView.setLayoutParams(layoutParams)
|
||||
faceRectView.setLayoutParams(layoutParams)
|
||||
return layoutParams
|
||||
@@ -440,6 +458,9 @@ class FacePayPresentation(
|
||||
.previewOn(binding.dualCameraTexturePreviewRgb)
|
||||
.cameraListener(cameraListener)
|
||||
.build()
|
||||
rgbCameraHelper!!.setSurfaceFrameCallback { frame ->
|
||||
activity.facePayFragment?.loadBitmap(frame)
|
||||
}
|
||||
rgbCameraHelper!!.init()
|
||||
// rgbCameraHelper!!.start()
|
||||
}
|
||||
@@ -543,7 +564,6 @@ class FacePayPresentation(
|
||||
)
|
||||
// 识别成功
|
||||
binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList)
|
||||
ToastUtils.showToast("识别到人脸信息")
|
||||
}
|
||||
|
||||
if (facePreviewInfoList.isEmpty() || (lastFaceTrackId != facePreviewInfoList[0]!!.trackId)) {
|
||||
@@ -561,11 +581,30 @@ class FacePayPresentation(
|
||||
}
|
||||
}
|
||||
private var lastFaceTrackId: Int = -1 // 上一次的人脸信息
|
||||
|
||||
fun updateImage(bitmap: Bitmap) {
|
||||
activity.runOnUiThread {
|
||||
// binding.ivPreviewImage.setImageBitmap(bitmap)
|
||||
}
|
||||
private var mDialogWaiting:CustomDialog?=null
|
||||
/**
|
||||
* 显示等待提示框
|
||||
*/
|
||||
fun showWaitingDialog(tip: String?): Dialog? {
|
||||
hideWaitingDialog()
|
||||
val view = View.inflate(activity, R.layout.dialog_waiting, null)
|
||||
if (!TextUtils.isEmpty(tip)) (view.findViewById<View?>(R.id.tvTip) as TextView).text = tip
|
||||
mDialogWaiting = CustomDialog(activity, view, R.style.MyDialog)
|
||||
mDialogWaiting!!.show()
|
||||
mDialogWaiting!!.setCancelable(true)
|
||||
return mDialogWaiting
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏等待提示框
|
||||
*/
|
||||
fun hideWaitingDialog() {
|
||||
mDialogWaiting?.dismiss()
|
||||
mDialogWaiting = null
|
||||
}
|
||||
|
||||
override fun onDisplayRemoved() {
|
||||
super.onDisplayRemoved()
|
||||
onDismissListener()
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.sw.dualscreen.presentation.pay
|
||||
|
||||
import android.app.Presentation
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.text.SpannedString
|
||||
import android.text.style.AbsoluteSizeSpan
|
||||
import android.view.Display
|
||||
import androidx.core.text.buildSpannedString
|
||||
import com.sw.dualscreen.activity.PayActivity
|
||||
import com.sw.dualscreen.databinding.PresentationQrcodePayBinding
|
||||
import com.sw.dualscreen.ext.load
|
||||
|
||||
class QrCodePayPresentation(
|
||||
val activity: PayActivity,
|
||||
display: Display,
|
||||
private val onDismissListener: () -> Unit = {}
|
||||
) : Presentation(activity, display) {
|
||||
|
||||
private lateinit var binding: PresentationQrcodePayBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = PresentationQrcodePayBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
window?.setBackgroundDrawableResource(android.R.color.transparent)
|
||||
initView()
|
||||
}
|
||||
|
||||
var foodName: String? = null
|
||||
var payAmount: String? = null
|
||||
var payQrCodePic: Any? = null
|
||||
private fun initView() {
|
||||
binding.tvFoodName.text = foodName
|
||||
binding.tvRealAmount.text = getAmountText(payAmount ?: "")
|
||||
binding.ivPayQrCode.load(payQrCodePic)
|
||||
}
|
||||
|
||||
private fun getAmountText(amount: String): SpannedString {
|
||||
return buildSpannedString {
|
||||
append("¥", AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.sw.dualscreen.presentation.pay
|
||||
|
||||
import android.app.Presentation
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.text.SpannedString
|
||||
import android.text.style.AbsoluteSizeSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.Display
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.text.buildSpannedString
|
||||
import com.sw.dualscreen.R
|
||||
import com.sw.dualscreen.activity.PayActivity
|
||||
import com.sw.dualscreen.databinding.PresentationScanQrcodePayBinding
|
||||
import com.sw.dualscreen.ext.gone
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.ext.visible
|
||||
|
||||
class ScanQrCodePayPresentation(
|
||||
val activity: PayActivity,
|
||||
display: Display,
|
||||
val type:Int,
|
||||
private val onDismissListener: () -> Unit = {}
|
||||
) : Presentation(activity, display) {
|
||||
|
||||
//type = 0,扫码支付默认显示二维码
|
||||
//type = 1,会员结算显示二维码,是会员则显示名字、头像、手机号、可用余额
|
||||
//type = 2,支付成功,是会员则显示名字、头像、手机号、可用余额
|
||||
|
||||
private lateinit var binding: PresentationScanQrcodePayBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = PresentationScanQrcodePayBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
window?.setBackgroundDrawableResource(android.R.color.transparent)
|
||||
initView()
|
||||
}
|
||||
|
||||
var foodName: String? = null
|
||||
var payAmount: String? = null
|
||||
var payQrCodePic: Any? = null
|
||||
private fun initView() {
|
||||
when(type) {
|
||||
0->{
|
||||
binding.layoutVip.gone()
|
||||
binding.layoutPaySuccess.gone()
|
||||
binding.layoutScanQrCode.visible()
|
||||
|
||||
binding.tvPayTip.text = "请扫码支付或出示付款码"
|
||||
binding.tvFoodName.text = foodName
|
||||
binding.tvRealAmount.text = getAmountText(payAmount ?: "")
|
||||
binding.ivPayQrCode.load(payQrCodePic)
|
||||
}
|
||||
1->{
|
||||
binding.layoutVip.visible()
|
||||
binding.layoutPaySuccess.gone()
|
||||
binding.layoutScanQrCode.visible()
|
||||
|
||||
binding.tvFoodName.text = foodName
|
||||
binding.tvRealAmount.text = getAmountText(payAmount ?: "")
|
||||
binding.ivPayQrCode.load(payQrCodePic)
|
||||
|
||||
binding.ivHeadPic.load(R.mipmap.ic_launcher)
|
||||
binding.tvUserName.text = "张三"
|
||||
binding.tvUserPhone.text = "132****5678"
|
||||
binding.tvUserBalance.text = getBalanceText("0.00")
|
||||
|
||||
binding.tvPayTip.text = getPayTip("-16.80", "22.00")
|
||||
}
|
||||
2->{
|
||||
binding.layoutVip.visible()
|
||||
binding.layoutPaySuccess.visible()
|
||||
binding.layoutScanQrCode.gone()
|
||||
|
||||
binding.ivHeadPic.load(R.mipmap.ic_launcher)
|
||||
binding.tvUserName.text = "张三"
|
||||
binding.tvUserPhone.text = "132****5678"
|
||||
binding.tvUserBalance.text = getBalanceText("0.00")
|
||||
|
||||
binding.tvPayInfo.text = "余额扣除 16.80 元,在线支付 20.00 元"
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPayTip(startAmount:String, endAmount: String): SpannedString {
|
||||
return buildSpannedString {
|
||||
append("余额扣除 ", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(startAmount, ForegroundColorSpan("#FF0A1428".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(" 元,还需支付 ", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(endAmount, ForegroundColorSpan("#FF0A1428".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(" 元", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBalanceText(amount: String): SpannedString {
|
||||
return buildSpannedString {
|
||||
append("¥", AbsoluteSizeSpan(20, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(amount, AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAmountText(amount: String): SpannedString {
|
||||
return buildSpannedString {
|
||||
append("¥", AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisplayRemoved() {
|
||||
super.onDisplayRemoved()
|
||||
onDismissListener()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user