人脸识别支付流程

This commit is contained in:
2025-11-28 09:13:29 +08:00
parent 88179e27b7
commit 9bcd7c9983
20 changed files with 561 additions and 216 deletions
@@ -4,8 +4,10 @@ import android.app.Dialog
import android.content.Context import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.hardware.display.DisplayManager
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils import android.text.TextUtils
import android.view.Display
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.TextView import android.widget.TextView
@@ -23,6 +25,12 @@ import timber.log.Timber
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() { 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 binding: VB
protected lateinit var context: Context protected lateinit var context: Context
private var mDialogWaiting: CustomDialog? = null 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.FacePayFragment
import com.sw.dualscreen.activity.fragment.pay.NumberPayFragment import com.sw.dualscreen.activity.fragment.pay.NumberPayFragment
import com.sw.dualscreen.activity.fragment.pay.PayResultFragment 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.databinding.ActivityPayBinding
import com.sw.dualscreen.model.response.FoodInfo 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.BaseViewModel
import com.sw.dualscreen.viewmodel.UserViewModel import com.sw.dualscreen.viewmodel.UserViewModel
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
@@ -40,10 +42,10 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
var foodInfo: FoodInfo? = null var foodInfo: FoodInfo? = null
private var qrCodePayFragment: QrCodePayFragment? = null private var qrCodePayFragment: ScanQrCodePayFragment? = null
private var cashPayFragment: CashPayFragment? = null private var cashPayFragment: CashPayFragment? = null
private var numberPayFragment: NumberPayFragment? = null private var numberPayFragment: NumberPayFragment? = null
private var facePayFragment: FacePayFragment? = null var facePayFragment: FacePayFragment? = null
private var payResultFragment: PayResultFragment? = null private var payResultFragment: PayResultFragment? = null
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@@ -53,33 +55,48 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
binding.tvFoodName.text = foodInfo?.foodName binding.tvFoodName.text = foodInfo?.foodName
binding.include.ivPageBack.setOnClickListener { finish() } binding.include.ivPageBack.setOnClickListener { finish() }
binding.include.tvPageTitle.text = "下单结算" binding.include.tvPageTitle.text = "下单结算"
val payQrCodeClickListener = View.OnClickListener { binding.btnPayQrCode.setOnClickListener {
if (qrCodePayFragment == null) { if (binding.btnPayQrCode.isChecked) {
qrCodePayFragment = QrCodePayFragment() return@setOnClickListener
} }
addFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE) showScanQrCodePay()
switchButton(true, false, false, false)
} }
binding.btnPayQrCode.setOnClickListener(payQrCodeClickListener)
binding.btnPayCash.setOnClickListener { binding.btnPayCash.setOnClickListener {
if (binding.btnPayCash.isChecked) {
return@setOnClickListener
}
if (cashPayFragment == null) { if (cashPayFragment == null) {
cashPayFragment = CashPayFragment() cashPayFragment = CashPayFragment()
} }
addFragment(cashPayFragment!!, TAG_PAY_CASH) showFragment(cashPayFragment!!, TAG_PAY_CASH)
switchButton(false, true, false, false) switchButton(false, true, false, false)
} }
binding.btnPayNumber.setOnClickListener { binding.btnPayNumber.setOnClickListener {
if (binding.btnPayNumber.isChecked) {
return@setOnClickListener
}
if (numberPayFragment == null) { if (numberPayFragment == null) {
numberPayFragment = NumberPayFragment() numberPayFragment = NumberPayFragment()
} }
addFragment(numberPayFragment!!, TAG_PAY_NUMBER) showFragment(numberPayFragment!!, TAG_PAY_NUMBER)
switchButton(false, false, true, false) switchButton(false, false, true, false)
} }
binding.btnPayFace.setOnClickListener { binding.btnPayFace.setOnClickListener {
if (binding.btnPayFace.isChecked) {
return@setOnClickListener
}
showFacePay() 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) { private fun switchButton(vararg arr: Boolean) {
@@ -93,38 +110,49 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
if (facePayFragment == null) { if (facePayFragment == null) {
facePayFragment = FacePayFragment() facePayFragment = FacePayFragment()
} }
addFragment(facePayFragment!!, TAG_PAY_FACE) showFragment(facePayFragment!!, TAG_PAY_FACE)
switchButton(false, false, false, true) switchButton(false, false, false, true)
} }
private fun addFragment(currentFragment: Fragment, tag: String) { private fun showFragment(fragment: Fragment, tag: String) {
runCatching { runCatching {
supportFragmentManager.beginTransaction().apply { supportFragmentManager.beginTransaction().apply {
val existFragment = supportFragmentManager.findFragmentByTag(tag) replace(R.id.fragmentContainerView, fragment)
if (existFragment == null) { commitNowAllowingStateLoss()
add(R.id.fragmentContainerView, currentFragment, tag)
}
val fragments = supportFragmentManager.fragments
fragments.forEach {
it?.let { fragment ->
if (fragment != currentFragment) {
hide(fragment)
}
}
}
show(currentFragment)
commitAllowingStateLoss()
} }
}.onFailure { }.onFailure {
it.printStackTrace() 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() { fun showPayResult() {
if (payResultFragment == null) { if (payResultFragment == null) {
payResultFragment = PayResultFragment() payResultFragment = PayResultFragment()
} }
addFragment(payResultFragment!!, TAG_PAY_RESULT) showFragment(payResultFragment!!, TAG_PAY_RESULT)
} }
override fun onDestroy() { override fun onDestroy() {
@@ -134,5 +162,22 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
facePayFragment?.presentation?.dismiss() facePayFragment?.presentation?.dismiss()
super.onDestroy() 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 package com.sw.dualscreen.activity.fragment.pay
import android.graphics.Bitmap
import com.sw.dualscreen.activity.PayActivity import com.sw.dualscreen.activity.PayActivity
import com.sw.dualscreen.activity.fragment.BaseFragment import com.sw.dualscreen.activity.fragment.BaseFragment
import com.sw.dualscreen.databinding.FragmentFacePayBinding import com.sw.dualscreen.databinding.FragmentFacePayBinding
import com.sw.dualscreen.presentation.pay.CashPayPresentation
import com.sw.dualscreen.presentation.pay.FacePayPresentation import com.sw.dualscreen.presentation.pay.FacePayPresentation
class FacePayFragment : BaseFragment<FragmentFacePayBinding>() { class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
@@ -37,6 +37,10 @@ class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
showSubScreen() showSubScreen()
} }
fun loadBitmap(frame: Bitmap) {
binding.ivFaceImage.setImageBitmap(frame)
}
private fun showSubScreen() { private fun showSubScreen() {
// 查找副屏(通常索引为1 // 查找副屏(通常索引为1
if (displays.size > 1) { if (displays.size > 1) {
@@ -45,6 +49,7 @@ class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
display = displays[1], display = displays[1],
userViewModel = payActivity!!.userViewModel, userViewModel = payActivity!!.userViewModel,
recognizeViewModel = payActivity!!.recognizeViewModel, recognizeViewModel = payActivity!!.recognizeViewModel,
// parentTextureView = binding.parentTextureView,
) { ) {
presentation?.dismiss() presentation?.dismiss()
}.also { }.also {
@@ -1,8 +1,14 @@
package com.sw.dualscreen.activity.fragment.pay 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.PayActivity
import com.sw.dualscreen.activity.fragment.BaseFragment import com.sw.dualscreen.activity.fragment.BaseFragment
import com.sw.dualscreen.databinding.FragmentPayResultBinding import com.sw.dualscreen.databinding.FragmentPayResultBinding
import com.sw.dualscreen.ext.load
class PayResultFragment: BaseFragment<FragmentPayResultBinding>() { class PayResultFragment: BaseFragment<FragmentPayResultBinding>() {
@@ -10,20 +16,25 @@ class PayResultFragment: BaseFragment<FragmentPayResultBinding>() {
return FragmentPayResultBinding.inflate(layoutInflater) return FragmentPayResultBinding.inflate(layoutInflater)
} }
private var payActivity: PayActivity? = null private var payActivity: PayActivity? = null
override fun initialize() { override fun initialize() {
payActivity = activity as PayActivity payActivity = activity as PayActivity
binding.btnBack.setOnClickListener { 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) { private fun getBalanceText(amount: String): SpannedString {
super.onHiddenChanged(hidden) return buildSpannedString {
//显示时重新查询接口 append("¥", AbsoluteSizeSpan(20, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
if (hidden.not()) { append(amount, AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
} }
} }
} }
@@ -8,22 +8,25 @@ import androidx.lifecycle.lifecycleScope
import com.sw.dualscreen.R import com.sw.dualscreen.R
import com.sw.dualscreen.activity.PayActivity import com.sw.dualscreen.activity.PayActivity
import com.sw.dualscreen.activity.fragment.BaseFragment import com.sw.dualscreen.activity.fragment.BaseFragment
import com.sw.dualscreen.databinding.FragmentQrcodePayBinding
import com.sw.dualscreen.ext.load 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 com.sw.dualscreen.utils.countDownByFlow
import kotlinx.coroutines.Job 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 lateinit var payActivity: PayActivity
private var foodName: String? = null private var foodName: String? = null
private var payAmount: String? = null private var payAmount: String? = null
private var payQrCodePic: Any? = null private var payQrCodePic: Any? = null
var presentation: QrCodePayPresentation?=null var presentation: ScanQrCodePayPresentation?=null
override fun inflateViewBinding(): FragmentQrcodePayBinding { override fun inflateViewBinding(): FragmentScanQrcodePayBinding {
return FragmentQrcodePayBinding.inflate(layoutInflater) return FragmentScanQrcodePayBinding.inflate(layoutInflater)
} }
override fun initialize() { override fun initialize() {
@@ -55,7 +58,7 @@ class QrCodePayFragment: BaseFragment<FragmentQrcodePayBinding>() {
private fun showSubScreen() { private fun showSubScreen() {
// 查找副屏(通常索引为1 // 查找副屏(通常索引为1
if (displays.size > 1) { if (displays.size > 1) {
presentation = QrCodePayPresentation(activity = payActivity, display = displays[1]) { presentation = ScanQrCodePayPresentation(activity = payActivity, type = 0, display = displays[1]) {
presentation?.dismiss() presentation?.dismiss()
}.also { }.also {
it.foodName = foodName it.foodName = foodName
@@ -83,7 +86,7 @@ class QrCodePayFragment: BaseFragment<FragmentQrcodePayBinding>() {
binding.tvPayResult.text = "待支付(${seconds}s)..." binding.tvPayResult.text = "待支付(${seconds}s)..."
}, },
onFinish = { onFinish = {
binding.tvPayResult.text = "支付倒计时结束" binding.tvPayResult.text = "支付"
} }
) )
} }
@@ -102,7 +102,7 @@ class MainScreenPresentation(
binding = PresentationMainScreenBinding.inflate(layoutInflater) binding = PresentationMainScreenBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0 mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
window?.setBackgroundDrawableResource(android.R.color.transparent) window?.setBackgroundDrawableResource(android.R.color.white)
initView() initView()
setupArcCamera() setupArcCamera()
registerDataChange() registerDataChange()
@@ -713,8 +713,10 @@ class MainScreenPresentation(
val layoutParams = previewView.layoutParams val layoutParams = previewView.layoutParams
// layoutParams.width = (608.dp * 1.5).roundToInt() // layoutParams.width = (608.dp * 1.5).roundToInt()
// layoutParams.height = (456.dp * 1.5).roundToInt() // layoutParams.height = (456.dp * 1.5).roundToInt()
layoutParams.width = (600.dp * 1.5).roundToInt() // layoutParams.width = (600.dp * 1.5).roundToInt()
layoutParams.height = (400.dp * 1.5).roundToInt() // layoutParams.height = (450.dp * 1.5).roundToInt()
layoutParams.width = 1024
layoutParams.height = 768
previewView.setLayoutParams(layoutParams) previewView.setLayoutParams(layoutParams)
faceRectView.setLayoutParams(layoutParams) faceRectView.setLayoutParams(layoutParams)
return layoutParams return layoutParams
@@ -41,4 +41,9 @@ class CashPayPresentation(
append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) 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 package com.sw.dualscreen.presentation.pay
import android.Manifest import android.Manifest
import android.app.Dialog
import android.app.Presentation import android.app.Presentation
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Bitmap import android.graphics.Bitmap
@@ -10,24 +11,26 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.Spanned import android.text.Spanned
import android.text.SpannedString import android.text.SpannedString
import android.text.TextUtils
import android.text.style.AbsoluteSizeSpan import android.text.style.AbsoluteSizeSpan
import android.view.Display import android.view.Display
import android.view.TextureView
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.text.buildSpannedString import androidx.core.text.buildSpannedString
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.arcsoft.face.ErrorInfo import com.arcsoft.face.ErrorInfo
import com.sw.dualscreen.GlobalKey
import com.sw.dualscreen.R import com.sw.dualscreen.R
import com.sw.dualscreen.activity.PayActivity import com.sw.dualscreen.activity.PayActivity
import com.sw.dualscreen.databinding.PresentationFacePayBinding import com.sw.dualscreen.databinding.PresentationFacePayBinding
import com.sw.dualscreen.ext.dp import com.sw.dualscreen.ext.load
import com.sw.dualscreen.presentation.MainScreenPresentation import com.sw.dualscreen.view.CustomDialog
import com.sw.dualscreen.utils.SPUtil
import com.sw.dualscreen.viewmodel.UserViewModel import com.sw.dualscreen.viewmodel.UserViewModel
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.ConfigUtil 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 com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import kotlin.math.roundToInt
class FacePayPresentation( class FacePayPresentation(
val activity: PayActivity, val activity: PayActivity,
display: Display, display: Display,
val userViewModel: UserViewModel, val userViewModel: UserViewModel,
val recognizeViewModel: RecognizeViewModel, val recognizeViewModel: RecognizeViewModel,
// val //parentTextureView: TextureView,
private val onDismissListener: () -> Unit = {} private val onDismissListener: () -> Unit = {}
) : Presentation(activity, display) , ViewTreeObserver.OnGlobalLayoutListener { ) : Presentation(activity, display) , ViewTreeObserver.OnGlobalLayoutListener {
@@ -75,16 +78,20 @@ class FacePayPresentation(
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = PresentationFacePayBinding.inflate(layoutInflater) binding = PresentationFacePayBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
window?.setBackgroundDrawableResource(R.color.transparent) window?.setBackgroundDrawableResource(android.R.color.white)
initView() initView()
setupArcCamera() setupArcCamera()
registerDataChange() registerDataChange()
pauseCamera()
} }
override fun show() { override fun show() {
super.show() super.show()
resumeCamera() binding.root.postDelayed({
resumeCamera()
}, 1500)
} }
var foodName: String? = null var foodName: String? = null
@@ -92,6 +99,14 @@ class FacePayPresentation(
private fun initView() { private fun initView() {
binding.tvFoodName.text = foodName binding.tvFoodName.text = foodName
binding.tvRealAmount.text = getAmountText(payAmount ?: "") 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 { private fun getAmountText(amount: String): SpannedString {
@@ -104,6 +119,7 @@ class FacePayPresentation(
override fun onGlobalLayout() { override fun onGlobalLayout() {
Timber.tag(TAG).d("onGlobalLayout") Timber.tag(TAG).d("onGlobalLayout")
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().removeOnGlobalLayoutListener(this) binding.dualCameraTexturePreviewRgb.getViewTreeObserver().removeOnGlobalLayoutListener(this)
//parentTextureView.getViewTreeObserver().removeOnGlobalLayoutListener(this)
openCamera() openCamera()
} }
private fun openCamera() { private fun openCamera() {
@@ -249,17 +265,16 @@ class FacePayPresentation(
val userId = faceEntity.userName val userId = faceEntity.userName
if (userId == null ) return@Observer if (userId == null ) return@Observer
activity.runOnUiThread { 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( // userViewModel.getUserNutritionData(
// userId = userId, // userId = userId,
// foodId = currentFood!!.id!! // foodId = currentFood!!.id!!
@@ -274,6 +289,7 @@ class FacePayPresentation(
private fun initArcView() { private fun initArcView() {
//在布局结束后才做初始化操作 //在布局结束后才做初始化操作
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().addOnGlobalLayoutListener(this) binding.dualCameraTexturePreviewRgb.getViewTreeObserver().addOnGlobalLayoutListener(this)
//parentTextureView.getViewTreeObserver().addOnGlobalLayoutListener(this)
recognizeViewModel.getCompareResultList().getValue() recognizeViewModel.getCompareResultList().getValue()
} }
@@ -337,8 +353,10 @@ class FacePayPresentation(
val layoutParams = previewView.layoutParams val layoutParams = previewView.layoutParams
// layoutParams.width = (608.dp * 1.5).roundToInt() // layoutParams.width = (608.dp * 1.5).roundToInt()
// layoutParams.height = (456.dp * 1.5).roundToInt() // layoutParams.height = (456.dp * 1.5).roundToInt()
layoutParams.width = (600.dp * 1.5).roundToInt() // layoutParams.width = (608.dp * 1.5).roundToInt()
layoutParams.height = (400.dp * 1.5).roundToInt() // layoutParams.height = (456.dp * 1.5).roundToInt()
layoutParams.width = 1024
layoutParams.height = 768
previewView.setLayoutParams(layoutParams) previewView.setLayoutParams(layoutParams)
faceRectView.setLayoutParams(layoutParams) faceRectView.setLayoutParams(layoutParams)
return layoutParams return layoutParams
@@ -440,6 +458,9 @@ class FacePayPresentation(
.previewOn(binding.dualCameraTexturePreviewRgb) .previewOn(binding.dualCameraTexturePreviewRgb)
.cameraListener(cameraListener) .cameraListener(cameraListener)
.build() .build()
rgbCameraHelper!!.setSurfaceFrameCallback { frame ->
activity.facePayFragment?.loadBitmap(frame)
}
rgbCameraHelper!!.init() rgbCameraHelper!!.init()
// rgbCameraHelper!!.start() // rgbCameraHelper!!.start()
} }
@@ -543,7 +564,6 @@ class FacePayPresentation(
) )
// 识别成功 // 识别成功
binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList) binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList)
ToastUtils.showToast("识别到人脸信息")
} }
if (facePreviewInfoList.isEmpty() || (lastFaceTrackId != facePreviewInfoList[0]!!.trackId)) { if (facePreviewInfoList.isEmpty() || (lastFaceTrackId != facePreviewInfoList[0]!!.trackId)) {
@@ -561,11 +581,30 @@ class FacePayPresentation(
} }
} }
private var lastFaceTrackId: Int = -1 // 上一次的人脸信息 private var lastFaceTrackId: Int = -1 // 上一次的人脸信息
private var mDialogWaiting:CustomDialog?=null
fun updateImage(bitmap: Bitmap) { /**
activity.runOnUiThread { * 显示等待提示框
// binding.ivPreviewImage.setImageBitmap(bitmap) */
} 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()
}
}
+13 -7
View File
@@ -17,19 +17,25 @@
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="509dp"
android:layout_marginHorizontal="32dp" android:layout_marginHorizontal="32dp"
android:layout_marginTop="64dp"> android:layout_marginTop="64dp">
<FrameLayout <!-- <FrameLayout-->
android:id="@+id/flCameraPreview" <!-- android:id="@+id/flCameraPreview"-->
android:layout_width="match_parent" <!-- android:layout_width="match_parent"-->
android:layout_height="match_parent" /> <!-- android:layout_height="match_parent" />-->
<!-- <TextureView-->
<!-- android:id="@+id/parentTextureView"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:visibility="visible" />-->
<ImageView <ImageView
android:id="@+id/ivFacePhoto" android:id="@+id/ivFaceImage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="510dp" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
tools:ignore="ContentDescription" tools:ignore="ContentDescription"
tools:src="@mipmap/ic_launcher" /> tools:src="@mipmap/ic_launcher" />
@@ -22,11 +22,12 @@
android:paddingTop="32dp" android:paddingTop="32dp"
android:paddingBottom="47dp"> android:paddingBottom="47dp">
<ImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/ivHeadPic" android:id="@+id/ivHeadPic"
android:layout_width="120dp" android:layout_width="120dp"
android:layout_height="120dp" android:layout_height="120dp"
android:src="@mipmap/ic_launcher" android:src="@mipmap/ic_launcher"
app:shapeAppearance="@style/CircleStyle"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@@ -158,14 +159,9 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center_horizontal" android:gravity="center"
android:orientation="vertical"> android:orientation="vertical">
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<ImageView <ImageView
android:layout_width="120dp" android:layout_width="120dp"
android:layout_height="120dp" android:layout_height="120dp"
@@ -208,10 +204,6 @@
android:textSize="30sp" android:textSize="30sp"
android:textStyle="bold" /> android:textStyle="bold" />
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout> </LinearLayout>
@@ -67,8 +67,8 @@
<FrameLayout <FrameLayout
android:id="@+id/flFace" android:id="@+id/flFace"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="400dp" android:layout_height="456dp"
android:layout_marginHorizontal="32dp" android:layout_marginHorizontal="28dp"
android:layout_marginTop="56dp"> android:layout_marginTop="56dp">
<TextureView <TextureView
@@ -82,6 +82,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<!-- <ImageView-->
<!-- android:id="@+id/ivPreviewImage"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent" />-->
<!-- <ImageView--> <!-- <ImageView-->
<!-- android:id="@+id/ivFaceRecMask"--> <!-- android:id="@+id/ivFaceRecMask"-->
<!-- android:layout_width="match_parent"--> <!-- android:layout_width="match_parent"-->
@@ -104,8 +108,8 @@
<FrameLayout <FrameLayout
android:id="@+id/fl_recognize_ir" android:id="@+id/fl_recognize_ir"
android:layout_width="15dp" android:layout_width="1.3333dp"
android:layout_height="10dp" android:layout_height="1dp"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:visibility="visible"> android:visibility="visible">
@@ -34,7 +34,7 @@
<FrameLayout <FrameLayout
android:id="@+id/flCameraView" android:id="@+id/flCameraView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="400dp" android:layout_height="456dp"
android:layout_marginHorizontal="28dp" android:layout_marginHorizontal="28dp"
android:visibility="visible"> android:visibility="visible">
@@ -79,13 +79,13 @@
<ImageView <ImageView
android:id="@+id/ivPreviewImage" android:id="@+id/ivPreviewImage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="400dp" android:layout_height="456dp"
tools:background="@mipmap/ic_launcher"/> tools:background="@mipmap/ic_launcher"/>
<ImageView <ImageView
android:id="@+id/ivRecImage" android:id="@+id/ivRecImage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="400dp" android:layout_height="456dp"
tools:background="@mipmap/ic_launcher"/> tools:background="@mipmap/ic_launcher"/>
<ImageView <ImageView
@@ -229,8 +229,8 @@
<FrameLayout <FrameLayout
android:id="@+id/fl_recognize_ir" android:id="@+id/fl_recognize_ir"
android:layout_width="15dp" android:layout_width="1.3333dp"
android:layout_height="10dp" android:layout_height="1dp"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:visibility="visible"> android:visibility="visible">
@@ -1,66 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFE7EFF8">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layout_margin="28dp"
android:background="@drawable/setting_border"
android:orientation="vertical">
<TextView
android:id="@+id/tvFoodName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="210dp"
android:textColor="#FF0A1428"
android:textSize="40sp"
android:textStyle="bold"
tools:text="岐山臊子面" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="55dp"
android:text="应付金额"
android:textColor="#FF5E7585"
android:textSize="24sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tvRealAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:textColor="#FFFF3232"
android:textSize="32sp"
android:textStyle="bold"
tools:text="¥36.80" />
<ImageView
android:id="@+id/ivPayQrCode"
android:layout_width="333dp"
android:layout_height="333dp"
android:layout_marginTop="56dp"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_qrcode" />
<TextView
android:id="@+id/tvPayTip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="55dp"
android:text="请扫码支付或出示付款码"
android:textColor="#FF5E7585"
android:textSize="24sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>
</FrameLayout>
@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#FFE7EFF8">
<LinearLayout
android:id="@+id/layoutScanQrCode"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layout_margin="28dp"
android:background="@drawable/setting_border"
android:orientation="vertical"
android:visibility="visible">
<TextView
android:id="@+id/tvFoodName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="327dp"
android:textColor="#FF0A1428"
android:textSize="40sp"
android:textStyle="bold"
tools:text="岐山臊子面" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="55dp"
android:text="应付金额"
android:textColor="#FF5E7585"
android:textSize="24sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tvRealAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:textColor="#FFFF3232"
android:textSize="48sp"
android:textStyle="bold"
tools:text="¥36.80" />
<ImageView
android:id="@+id/ivPayQrCode"
android:layout_width="333dp"
android:layout_height="333dp"
android:layout_marginTop="56dp"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_qrcode" />
<TextView
android:id="@+id/tvPayTip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="55dp"
android:text="请扫码支付或出示付款码"
android:textColor="#FF5E7585"
android:textSize="24sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>
<LinearLayout
android:id="@+id/layoutPaySuccess"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layout_margin="28dp"
android:background="@drawable/setting_border"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="471dp"
android:src="@drawable/ic_pay_success" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:text="支付成功"
android:textColor="#ff00c864"
android:textSize="48sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvPayInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="55dp"
android:textColor="#FF5E7585"
android:textSize="24sp"
tools:text="余额扣除 16.80 元,在线支付 20.00 元" />
</LinearLayout>
<androidx.cardview.widget.CardView
android:id="@+id/layoutVip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@color/white"
android:layout_marginTop="56dp"
android:layout_marginHorizontal="56dp"
app:cardCornerRadius="5dp"
app:cardElevation="0dp"
android:visibility="visible">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="28dp">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/ivHeadPic"
android:layout_width="84dp"
android:layout_height="84dp"
tools:src="@mipmap/ic_launcher"
android:layout_marginTop="28dp"
app:shapeAppearance="@style/CircleStyle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="27dp"
android:textColor="#ff0a1428"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/tvUserPhone"
app:layout_constraintStart_toEndOf="@id/ivHeadPic"
app:layout_constraintTop_toTopOf="@id/ivHeadPic"
app:layout_constraintVertical_chainStyle="packed"
tools:text="DAMIHU" />
<TextView
android:id="@+id/tvUserPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:textColor="#ff889ac2"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="@id/ivHeadPic"
app:layout_constraintStart_toStartOf="@id/tvUserName"
app:layout_constraintTop_toBottomOf="@id/tvUserName"
tools:text="138****8000" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="28dp"
android:background="#FFDBE5FB"
app:layout_constraintTop_toBottomOf="@id/ivHeadPic" />
<TextView
android:id="@+id/tvBalanceName"
android:layout_width="wrap_content"
android:layout_height="79dp"
android:text="可用余额"
android:gravity="center_vertical"
android:textColor="#ff889ac2"
android:textSize="24sp"
app:layout_constraintStart_toStartOf="@id/ivHeadPic"
app:layout_constraintTop_toBottomOf="@id/divider" />
<TextView
android:id="@+id/tvUserBalance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF0A1428"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="@id/tvBalanceName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tvBalanceName"
tools:text="¥16.80" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
+6
View File
@@ -166,4 +166,10 @@
<!-- 遮罩层 --> <!-- 遮罩层 -->
<item name="android:backgroundDimAmount">0.5</item> <item name="android:backgroundDimAmount">0.5</item>
</style> </style>
<style name="CircleStyle">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
</resources> </resources>
@@ -88,8 +88,10 @@ public class ConfigUtil {
* 默认相机分辨率 * 默认相机分辨率
*/ */
// private static final String DEFAULT_PREVIEW_SIZE = "1280x720"; // private static final String DEFAULT_PREVIEW_SIZE = "1280x720";
private static final String DEFAULT_PREVIEW_SIZE = "600x400"; // private static final String DEFAULT_PREVIEW_SIZE = "608x456";
// private static final String DEFAULT_PREVIEW_SIZE = "400x640"; private static final String DEFAULT_PREVIEW_SIZE = "1024x768";
// private static final String DEFAULT_PREVIEW_SIZE = "800x600";
// private static final String DEFAULT_PREVIEW_SIZE = "640x480";
/** /**
@@ -1,5 +1,6 @@
package com.sw.plate.utils.arcface.camera; package com.sw.plate.utils.arcface.camera;
import android.graphics.Bitmap;
import android.graphics.ImageFormat; import android.graphics.ImageFormat;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture;
@@ -42,8 +43,10 @@ public class DualCameraHelper implements Camera.PreviewCallback {
private Integer specificCameraId = null; private Integer specificCameraId = null;
private CameraListener cameraListener; private CameraListener cameraListener;
private static final int MIN_PREVIEW_WIDTH = 720; // private static final int MIN_PREVIEW_WIDTH = 720;
private static final int MIN_PREVIEW_HEIGHT = 720; // private static final int MIN_PREVIEW_HEIGHT = 720;
private static final int MIN_PREVIEW_WIDTH = 800;
private static final int MIN_PREVIEW_HEIGHT = 600;
private DualCameraHelper(Builder builder) { private DualCameraHelper(Builder builder) {
previewDisplayView = builder.previewDisplayView; previewDisplayView = builder.previewDisplayView;
@@ -60,6 +63,16 @@ public class DualCameraHelper implements Camera.PreviewCallback {
} }
} }
public interface SurfaceFrameCallback {
void onFrameCallback(Bitmap frame);
}
private SurfaceFrameCallback surfaceFrameCallback;
public void setSurfaceFrameCallback(SurfaceFrameCallback callback) {
this.surfaceFrameCallback = callback;
}
public void init() { public void init() {
if (previewDisplayView instanceof TextureView) { if (previewDisplayView instanceof TextureView) {
((TextureView) this.previewDisplayView).setSurfaceTextureListener(textureListener); ((TextureView) this.previewDisplayView).setSurfaceTextureListener(textureListener);
@@ -126,6 +139,12 @@ public class DualCameraHelper implements Camera.PreviewCallback {
return; return;
} }
List<Camera.Size> supportedPreviewSize = getCommonSupportedPreviewSize(); List<Camera.Size> supportedPreviewSize = getCommonSupportedPreviewSize();
StringBuilder stringBuilder = new StringBuilder();
for (Camera.Size size : supportedPreviewSize) {
stringBuilder.append("width=").append(size.width).append(",")
.append("height=").append(size.height).append(",");
}
Log.d(TAG, "start: "+stringBuilder);
//相机数量为2则打开1,1则打开0,相机ID 1为前置,0为后置 //相机数量为2则打开1,1则打开0,相机ID 1为前置,0为后置
mCameraId = Camera.getNumberOfCameras() - 1; mCameraId = Camera.getNumberOfCameras() - 1;
//若指定了相机ID且该相机存在,则打开指定的相机 //若指定了相机ID且该相机存在,则打开指定的相机
@@ -371,7 +390,12 @@ public class DualCameraHelper implements Camera.PreviewCallback {
@Override @Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
if (surfaceFrameCallback!=null) {
if (previewDisplayView instanceof TextureView) {
Bitmap frame = ((TextureView) previewDisplayView).getBitmap();
surfaceFrameCallback.onFrameCallback(frame);
}
}
} }
}; };
private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {