refactor(servicing): 重构极光推送相关代码并优化面部识别功能

- 移除了极光推送相关的冗余代码和配置- 更新了极光推送 SDK版本
- 优化了面部识别流程,增加了弱光环境处理
- 调整了车型信息展示逻辑
- 修复了一些潜在的 bug 和性能问题
This commit is contained in:
songzhiling
2025-05-23 20:25:13 +08:00
parent f29cac2d73
commit 3344e5acd8
16 changed files with 183 additions and 272 deletions

View File

@ -27,7 +27,7 @@ class MainActivity : ComponentActivity() {
.fillMaxSize()
.clickable {
val uri =
"zd.assist://app?taskCode=ZD240823100724&driverName=宋志领&driverPhone=17630035658&rescueVehicle=沪88888".toUri()
"zd.assist://app?taskCode=ZD250521100797&driverName=宋志领&driverPhone=17630035658&rescueVehicle=沪88888".toUri()
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
}

View File

@ -9,9 +9,9 @@ crashreport = "4.0.4"
fastjson = "1.2.69"
glide = "4.16.0"
gson = "2.11.0"
jcore = "3.3.2"
jcore = "5.0.0"
faceDetection = "16.1.7"
jpush = "4.8.1"
jpush = "5.6.0"
location = "5.6.1"
loggingInterceptor = "4.11.0"
#这是一个长期维护的版本,不建议升级
@ -74,7 +74,6 @@ crashreport = { module = "com.tencent.bugly:crashreport", version.ref = "crashre
fastjson = { module = "com.alibaba:fastjson", version.ref = "fastjson" }
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
jcore = { module = "cn.jiguang.sdk:jcore", version.ref = "jcore" }
jpush = { module = "cn.jiguang.sdk:jpush", version.ref = "jpush" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }

View File

@ -19,21 +19,6 @@ android {
vectorDrawables {
useSupportLibrary true
}
manifestPlaceholders = [
JPUSH_PKGNAME : "${applicationId}",
JPUSH_APPKEY : "a87e46d05e9f095a2b47a304", //JPush 上注册的包名对应的 Appkey.e6c51448340caba93fd418
JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
XIAOMI_APPID : "MI-2882303761518149120",
XIAOMI_APPKEY : "MI-5381814934120",//MI-小米的APPKEY
HUAWEI_APPID : "appid=100923923",//appid=华为的APPID"
OPPO_APPKEY : "OP-c8ce8eafcd3940ceb85c1ccbee8863c7",//OP-oppo的APPKEY
OPPO_APPID : "OP-30136992",//OP-oppo的APPID
OPPO_APPSECRET: "OP-25e2baa85b7946b1b365af515515c42d",//OP-oppo的APPSECRET
VIVO_APPKEY : "cfd443e2a1757cf537361588c988a12a",//vivo的APPKEY
VIVO_APPID : "105470845",//vivo的APPID
]
}
buildTypes {
@ -73,7 +58,7 @@ publishing {
release(MavenPublication) {
groupId = 'io.github.szl9'
artifactId = 'zd_servicing'
version = "1.0.1.9.9.100"
version = "1.0.1.9.9.120"
pom {
packaging = "aar"
@ -182,7 +167,6 @@ dependencies {
// // JPush
api libs.jpush
api libs.jcore
api libs.gson
// 网络

View File

@ -4,9 +4,6 @@
<uses-sdk tools:overrideLibrary="androidx.camera.view,androidx.camera:camera-camera2,androidx.camera.camera2,androidx.camera.lifecycle,androidx.camera.core" />
<permission
android:name="${applicationId}.permission.JPUSH_MESSAGE"
android:protectionLevel="signature" /> <!-- 位置相关权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
@ -207,70 +204,6 @@
android:theme="@style/Theme.Dealer" />
<service
android:name="com.za.service.jpush.PushService"
android:enabled="true"
android:exported="false" />
<service
android:name="cn.jpush.android.service.PushService"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="cn.jpush.android.intent.REGISTER" />
<action android:name="cn.jpush.android.intent.REPORT" />
<action android:name="cn.jpush.android.intent.PushService" />
<action android:name="cn.jpush.android.intent.PUSH_TIME" />
</intent-filter>
</service>
<receiver
android:name="com.za.service.jpush.JPushReceiver"
android:enabled="true"
android:exported="true"
tools:node="replace">
<intent-filter>
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_ACTION" />
<action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED_ACTION" />
<action android:name="cn.jpush.android.intent.CONNECTION" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
<category android:name="${applicationId}" />
</intent-filter>
<intent-filter android:priority="1000">
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />
<!-- Required 显示通知栏 -->
<category android:name="${applicationId}" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<!-- Optional -->
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver
android:name="com.za.service.jpush.MyJPushMessageReceiver"
android:exported="true">
<intent-filter>
<action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_ACTION" />
<action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED_ACTION" />
<action android:name="cn.jpush.android.intent.CONNECTION" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<receiver
android:name="com.za.service.ZdPushServiceReceive"
android:exported="false">
@ -279,10 +212,6 @@
</intent-filter>
</receiver>
<service
android:name="cn.jpush.android.service.DaemonService"
android:enabled="true"
android:exported="true" />
</application>
</manifest>

View File

@ -1,9 +1,11 @@
package com.za.base
import android.os.Build
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.Composable
import androidx.core.view.WindowCompat
import com.tencent.smtt.sdk.QbSdk
import com.za.base.BaseVm.Companion.showTipDialog
import com.za.base.theme.DealerTheme
@ -16,9 +18,14 @@ abstract class BaseActivity : PushMessageActivity() {
override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
enableEdgeToEdge() // 可选:设置导航栏图标颜色(深色/浅色)
setContent {
DealerTheme {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val windowInsetsController =
WindowCompat.getInsetsController(window, this.window.decorView)
windowInsetsController.isAppearanceLightStatusBars = false
}
ContentView()
if (LoadingManager.showLoading.value) {
LoadingManager.LoadingView()

View File

@ -10,11 +10,12 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
@ -89,17 +90,17 @@ fun NetworkWeakView(netWarnBean : NetWarnBean) {
tint = Color(0xFFFF9800),
modifier = Modifier.size(24.dp))
}
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
Text(text = "提醒",
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
color = Color(0xFF424242),
fontSize = 14.sp)
Text(text = "网络异常提醒:",
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
color = Color(0xFF424242),
fontSize = 14.sp)
Text(text = "当前线路异常,是否前往切换线路",
style = MaterialTheme.typography.bodyMedium,
color = Color(0xFF757575),
fontSize = 12.sp)
}
Spacer(modifier = Modifier.width(5.dp))
Text(text = "当前网络异常,可以在线路检测中检测线路并切换!",
style = MaterialTheme.typography.bodyMedium,
color = Color(0xFF757575),
fontSize = 12.sp)
}
Box(modifier = Modifier
@ -109,7 +110,7 @@ fun NetworkWeakView(netWarnBean : NetWarnBean) {
.background(color = Color(0xFFFF9800), shape = RoundedCornerShape(5.dp))
.padding(horizontal = 10.dp, vertical = 5.dp),
contentAlignment = Alignment.Center) {
Text("完成", color = Color.White, style = MaterialTheme.typography.labelLarge)
Text("切换", color = Color.White, style = MaterialTheme.typography.labelLarge)
}
}
}

View File

@ -7,7 +7,6 @@ import com.tencent.mmkv.MMKV
import com.za.base.AppConfig
import com.za.base.Const
import com.za.bean.db.order.OrderInfo
import com.za.common.log.LogUtil
import com.za.room.RoomHelper
import com.za.room.db.user.DriverInfoBean
@ -52,13 +51,11 @@ object GlobalData : GlobalLocalData() {
if (field == null) {
field = localDriverInfoBean
}
LogUtil.print("get driverInfoBean", "获取司机信息: $field")
return field
}
set(value) {
localDriverInfoBean = value
field = value
LogUtil.print("set driverInfoBean", "司机信息: $field")
}
@ -126,6 +123,14 @@ object GlobalData : GlobalLocalData() {
mmkv.encode("isReviewEnv", value)
}
var isHasShowKeepAlive : Boolean
get() {
return mmkv.decodeBool("isShowKeepAlive", false)
}
set(value) {
mmkv.encode("isShowKeepAlive", value)
}
fun clearUserCache() {
token = null
aesKey = null
@ -133,6 +138,7 @@ object GlobalData : GlobalLocalData() {
driverInfoBean = null
loginTime = null
isLoginRecognition = null
isHasShowKeepAlive = false
if (AppConfig.isRelease) {
networkEnv = if (AppConfig.isRelease) {

View File

@ -13,7 +13,6 @@ open class GlobalLocalData {
return try {
val driverInfo = MMKV.defaultMMKV()
.decodeParcelable("driverInfoBean", DriverInfoBean::class.java)
LogUtil.print("local_driverInfoBean", "获取司机信息: $driverInfo")
driverInfo
} catch (e : Exception) {
LogUtil.print("local_driverInfoBean", "获取司机信息失败: ${e.message}")
@ -26,7 +25,6 @@ open class GlobalLocalData {
if (value != null) {
lastLoginBean = value
}
LogUtil.print("set local_driverInfoBean", "保存司机信息: $value")
} catch (e : Exception) {
LogUtil.print("set local_driverInfoBean", "保存司机信息失败: ${e.message}")
}

View File

@ -1,50 +0,0 @@
package com.za.service.jpush
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import cn.jpush.android.api.JPushInterface
import com.za.common.GlobalData
import com.za.common.log.LogUtil
import com.za.service.ServiceManager
/**
* Created by zhangj on 2019/4/4.
*/
class JPushReceiver : BroadcastReceiver() {
override fun onReceive(context : Context, intent : Intent) {
val bundle = intent.extras
LogUtil.print("JpushMessage ", "onReceive==" + "action:" + intent.action)
if (intent.action == null || bundle == null) {
return
}
when (intent.action) {
JPushInterface.ACTION_REGISTRATION_ID -> {
val regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID)
GlobalData.regid = regId
LogUtil.print("JpushMessage ", "Registration successful: $regId")
}
JPushInterface.ACTION_MESSAGE_RECEIVED -> {
val msg = bundle.getString(JPushInterface.EXTRA_MESSAGE)
if (msg.isNullOrBlank()) {
return
}
Handler(Looper.getMainLooper()).post {
LogUtil.print("JpushMessage ", "Received message: $msg")
ServiceManager.handlerPushMsg(msg)
}
}
JPushInterface.ACTION_NOTIFICATION_RECEIVED -> {
val title = bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE)
LogUtil.print("JPushReceiver:", "ACTION_NOTIFICATION_RECEIVED title: $title")
}
else -> {}
}
}
}

View File

@ -1,71 +0,0 @@
package com.za.service.jpush
import android.content.Context
import android.util.Log
import cn.jpush.android.api.CmdMessage
import cn.jpush.android.api.JPushMessage
import cn.jpush.android.service.JPushMessageReceiver
import com.za.common.log.LogUtil
/**
* 自定义JPush message 接收器,包括操作tag/alias的结果返回(仅仅包含tag/alias新接口部分)
*/
class MyJPushMessageReceiver : JPushMessageReceiver() {
override fun onRegister(context: Context, s: String) {
super.onRegister(context, s)
LogUtil.print("JPushConnected onRegister", "REGID$s")
}
override fun onConnected(context: Context, b: Boolean) {
super.onConnected(context, b)
LogUtil.print("JPushConnected", "极光连接情况:$b")
// Global.isJpushConnected = b;
// if (b && null != Global.VEHICLE_INFO && !Global.isAliasSuccess)
// JPushInterface.setAlias(context, 5, AppUrlConfig.isRelease ? (Global.VEHICLE_INFO.vehicleId + "") : (Global.JPUSH_PREFIX + Global.VEHICLE_INFO.vehicleId));
}
override fun onTagOperatorResult(context: Context, jPushMessage: JPushMessage) {
// TagAliasOperatorHelper.getInstance().onTagOperatorResult(context, jPushMessage);
super.onTagOperatorResult(context, jPushMessage)
}
override fun onCheckTagOperatorResult(context: Context, jPushMessage: JPushMessage) {
// TagAliasOperatorHelper.getInstance().onCheckTagOperatorResult(context, jPushMessage);
super.onCheckTagOperatorResult(context, jPushMessage)
}
override fun onAliasOperatorResult(context: Context, jPushMessage: JPushMessage) {
// LogUtil.getInstance().print("极光 alias", "0->" + JSON.toJSONString(jPushMessage));
// TagAliasOperatorHelper.getInstance().onAliasOperatorResult(context, jPushMessage);
super.onAliasOperatorResult(context, jPushMessage)
}
override fun onMobileNumberOperatorResult(context: Context, jPushMessage: JPushMessage) {
// TagAliasOperatorHelper.getInstance().onMobileNumberOperatorResult(context, jPushMessage);
super.onMobileNumberOperatorResult(context, jPushMessage)
}
override fun onCommandResult(context: Context, cmdMessage: CmdMessage) {
//注册失败+三方厂商注册回调
LogUtil.print("极光 厂商", "[onCommandResult] $cmdMessage");
//cmd为10000时说明为厂商token回调
if (cmdMessage.cmd == 10000 && cmdMessage.extra != null) {
val token = cmdMessage.extra.getString("token")
val platform = cmdMessage.extra.getInt("platform")
var deviceName = "unkown"
when (platform) {
1 -> deviceName = "小米"
2 -> deviceName = "华为"
3 -> deviceName = "魅族"
4 -> deviceName = "OPPO"
5 -> {
deviceName = "VIVO"
Log.e("厂商", "[onCommandResult] vivo:$token")
}
8 -> deviceName = "FCM"
}
LogUtil.print("极光 厂商", "获取到 $deviceName 的token:$token");
}
}
}

View File

@ -1,6 +0,0 @@
package com.za.service.jpush
import cn.jpush.android.service.JCommonService
class PushService : JCommonService()

View File

@ -25,6 +25,11 @@ import com.za.common.log.LogUtil
import com.za.ext.toJson
import com.za.net.CommonMethod
import com.za.service.mqtt.MyMqttClient
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Locale
import kotlin.math.abs
import kotlin.math.cos
@ -38,7 +43,8 @@ object ZdLocationManager : AMapLocationListener {
private var context : Context? = null
private var option : AMapLocationClientOption? = null
private const val NORMA_INTERVAL_TIME = 20000L // 普通的GPS上传时间间隔
private const val NORMA_INTERVAL_TIME = 20000L // GPS上传时间间隔
private const val LOCATION_GET_DURATION = 5 * 1000L
private const val LOCATION_CACHE_DURATION = 60 * 1000L // 1分钟的缓存时间
private const val LOCATION_SEARCH_RADIUS = 200f
private const val DEFAULT_TIMEOUT = 30000L
@ -46,6 +52,35 @@ object ZdLocationManager : AMapLocationListener {
private var globalLocation : AMapLocation? = null
private var lastSingleLocationTime = 0L
private var locationUploadJob : Job? = null
private fun startUploadLocationJob() {
stopUploadLocationJob()
locationUploadJob = CoroutineScope(Dispatchers.IO).launch {
while (true) {
delay(NORMA_INTERVAL_TIME)
if (GlobalData.currentLocation == null) {
LogUtil.print(TAG, "定位上传失败: location is null")
continue
}
if (System.currentTimeMillis() - (GlobalData.currentLocation?.time
?: System.currentTimeMillis()) > 1000 * 60 * 2
) {
LogUtil.print(TAG, "定位上传失败: location is old")
continue
}
uploadGpsRequest(GlobalData.currentLocation !!)
}
}
}
private fun stopUploadLocationJob() {
locationUploadJob?.cancel()
locationUploadJob = null
}
fun init(context : Context) {
this.context = context.applicationContext
initAMapLocationClient()
@ -72,7 +107,7 @@ object ZdLocationManager : AMapLocationListener {
isNeedAddress : Boolean = false) : AMapLocationClientOption =
AMapLocationClientOption().apply {
locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
interval = NORMA_INTERVAL_TIME
interval = LOCATION_GET_DURATION
isWifiScan = true
isLocationCacheEnable = false
httpTimeOut = DEFAULT_TIMEOUT
@ -89,6 +124,7 @@ object ZdLocationManager : AMapLocationListener {
}
try {
aMapLocationClient?.startLocation()
startUploadLocationJob()
LogUtil.print(TAG, "持续定位开启成功")
} catch (e : Exception) {
LogUtil.print(TAG, "持续定位开启失败: ${e.message}")
@ -101,6 +137,7 @@ object ZdLocationManager : AMapLocationListener {
aMapLocationClient?.onDestroy()
aMapLocationClient?.unRegisterLocationListener(this)
aMapLocationClient = null
stopUploadLocationJob()
LogUtil.print(TAG, "关闭持续定位成功")
} catch (e : Exception) {
LogUtil.print(TAG, "关闭持续定位失败: ${e.message}")
@ -119,7 +156,8 @@ object ZdLocationManager : AMapLocationListener {
}
GlobalData.currentLocation = location
uploadGpsRequest(location)
LogUtil.print(TAG,
"定位获取成功: lat=${location.latitude} lng=${location.longitude} time=${location.time} speed=${location.speed} ") // uploadGpsRequest(location)
}
private fun uploadGpsRequest(location : AMapLocation) {

View File

@ -57,7 +57,7 @@ class ServicePeopleRealActivity : AppCompatActivity() {
private var isActivityActive = true
private var currentStep = 0
private val steps = listOf("请保持面部居中", "请向左转头", "请向右转头", "请保持面部居中")
private val steps = listOf( "请向左转头", "请向右转头", "请保持面部居中")
private var isStepCompleted = false
private lateinit var viewFinder : PreviewView
@ -67,6 +67,10 @@ class ServicePeopleRealActivity : AppCompatActivity() {
private lateinit var retryButton : Button
private lateinit var confirmButton : Button
private lateinit var lowLightWarning : TextView
private var originalBrightness : Int = 0
private var hasAdjustedBrightness : Boolean = false
private val faceDetector = FaceDetection.getClient(FaceDetectorOptions.Builder()
.setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
.setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL)
@ -105,6 +109,11 @@ class ServicePeopleRealActivity : AppCompatActivity() {
previewImage = findViewById(R.id.previewImage)
retryButton = findViewById(R.id.retryButton)
confirmButton = findViewById(R.id.confirmButton)
// lowLightWarning = findViewById(R.id.lowLightWarning) // 保存原始亮度
// originalBrightness = window.attributes.screenBrightness.let {
// if (it != - 1f) it else 0.5f
// }.toInt()
}
private fun setupClickListeners() {
@ -149,7 +158,8 @@ class ServicePeopleRealActivity : AppCompatActivity() {
else -> {
LogUtil.print("人脸检测成功", faces[0].toString())
avatarBitmap = handlerBitmap(image.toBitmap(), image.imageInfo.rotationDegrees)
avatarBitmap = handlerBitmap(image.toBitmap(),
image.imageInfo.rotationDegrees)
LogUtil.print("人脸认证通过", faces[0].toString())
runOnUiThread {
showConfirmation()
@ -230,23 +240,27 @@ class ServicePeopleRealActivity : AppCompatActivity() {
private fun startCamera() {
lifecycleCameraController.setImageAnalysisAnalyzer(ContextCompat.getMainExecutor(this@ServicePeopleRealActivity),
FaceAnalyzer { handleFaceDetection(it) })
FaceAnalyzer(faceListener = {
handleFaceDetection(it)
}, lightListener = {
// handleLowLightCallback(it)
}))
}
private fun handleLowLightCallback(isLowLight : Boolean) {
if (isLowLight) {
handleLowLight()
} else {
restoreBrightness()
}
}
private fun handleFaceDetection(eulerY : Float) {
if (! isActivityActive) return
when (currentStep) {
0 -> {
if (abs(eulerY) < 15) {
if (! isStepCompleted) {
isStepCompleted = true
proceedToNextStep()
}
}
}
1 -> {
0 -> {
if (eulerY > 15) {
if (! isStepCompleted) {
isStepCompleted = true
@ -255,7 +269,7 @@ class ServicePeopleRealActivity : AppCompatActivity() {
}
}
2 -> {
1 -> {
if (eulerY < - 15) {
if (! isStepCompleted) {
isStepCompleted = true
@ -264,7 +278,7 @@ class ServicePeopleRealActivity : AppCompatActivity() {
}
}
3 -> {
2 -> {
if (abs(eulerY) < 15) {
if (! isStepCompleted) {
isStepCompleted = true
@ -321,10 +335,9 @@ class ServicePeopleRealActivity : AppCompatActivity() {
SpeechManager.releaseMediaPlayer()
when (currentStep) {
0 -> SpeechManager.playFaceCenter()
1 -> SpeechManager.playFaceLeft()
2 -> SpeechManager.playFaceRight()
3 -> SpeechManager.playFaceCenter()
0 -> SpeechManager.playFaceLeft()
1 -> SpeechManager.playFaceRight()
2 -> SpeechManager.playFaceCenter()
}
}
@ -422,13 +435,8 @@ class ServicePeopleRealActivity : AppCompatActivity() {
isActivityActive = false
}
override fun onDestroy() {
super.onDestroy()
isActivityActive = false
cameraExecutor.shutdown()
}
private class FaceAnalyzer(private val listener : (Float) -> Unit) : ImageAnalysis.Analyzer {
private class FaceAnalyzer(private val faceListener : (Float) -> Unit,
private val lightListener : (Boolean) -> Unit) : ImageAnalysis.Analyzer {
private val detector = FaceDetection.getClient(FaceDetectorOptions.Builder()
.setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST)
.setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_NONE)
@ -437,13 +445,22 @@ class ServicePeopleRealActivity : AppCompatActivity() {
@ExperimentalGetImage
override fun analyze(imageProxy : ImageProxy) {
val mediaImage = imageProxy.image
if (mediaImage != null) {
if (mediaImage != null) { // 检测图像亮度
val buffer = mediaImage.planes[0].buffer
val data = ByteArray(buffer.remaining())
buffer.get(data)
val averageBrightness = data.average()
// 如果平均亮度低于阈值,认为是弱光环境
lightListener(averageBrightness < 80)
val image =
InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
detector.process(image).addOnSuccessListener { faces ->
if (faces.isNotEmpty()) {
listener(faces[0].headEulerAngleY)
faceListener(faces[0].headEulerAngleY)
}
}.addOnCompleteListener {
imageProxy.close()
@ -454,6 +471,39 @@ class ServicePeopleRealActivity : AppCompatActivity() {
}
}
private fun handleLowLight() {
if (! hasAdjustedBrightness) { // 显示弱光提示
lowLightWarning.visibility = View.VISIBLE
// 调高屏幕亮度
val layoutParams = window.attributes
layoutParams.screenBrightness = 1f
window.attributes = layoutParams
hasAdjustedBrightness = true
}
}
private fun restoreBrightness() {
if (hasAdjustedBrightness) { // 隐藏弱光提示
lowLightWarning.visibility = View.GONE
// 恢复原始亮度
val layoutParams = window.attributes
layoutParams.screenBrightness = originalBrightness.toFloat()
window.attributes = layoutParams
hasAdjustedBrightness = false
}
}
override fun onDestroy() {
super.onDestroy() // 恢复原始亮度
restoreBrightness()
isActivityActive = false
cameraExecutor.shutdown()
}
companion object {
private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)

View File

@ -135,6 +135,7 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
override fun doFailure(code : Int, msg : String?) {
LoadingManager.hideLoading()
ToastUtils.showShort(msg)
LogUtil.print("接单失败", "request=$acceptOrderRequest msg=$msg")
}
})

View File

@ -1,6 +1,7 @@
package com.za.ui.servicing.in_servicing_setting
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -26,18 +27,21 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import coil.compose.AsyncImage
import com.za.base.AppConfig
import com.za.base.theme.black5
import com.za.base.theme.black65
import com.za.base.view.CommonButton
import com.za.bean.TaskNotesBean
import com.za.bean.db.order.OrderInfo
import com.za.servicing.R
import com.za.ui.h5.CommonH5Activity
@Composable
fun OrderRequirementsScreen(orderInfo : OrderInfo?) {
@ -50,9 +54,7 @@ fun OrderRequirementsScreen(orderInfo : OrderInfo?) {
Spacer(modifier = Modifier.height(12.dp))
OrderRequirementsItemView(title = "特殊提醒", content = orderInfo?.otherNotes)
OrderRequirementsItemView(title = "收费标准", content = orderInfo?.feeStandard)
if (! orderInfo?.carModel.isNullOrBlank()) {
CarModeView(orderInfo = orderInfo)
}
CarModeView(orderInfo = orderInfo)
OrderRequirementsItemView(title = "救援要求", content = orderInfo?.taskNotes)
OrderRequirementsItemView(title = "客户要求", content = orderInfo?.customerNotes)
Spacer(modifier = Modifier.height(16.dp))
@ -89,6 +91,7 @@ fun OrderRequirementsItemView(title : String?, content : String?) {
@Composable
fun CarModeView(orderInfo : OrderInfo?) {
val context = LocalContext.current
Column(modifier = Modifier
.fillMaxWidth()
.padding(vertical = 5.dp)) {
@ -97,7 +100,7 @@ fun CarModeView(orderInfo : OrderInfo?) {
contentDescription = null,
modifier = Modifier.size(16.dp))
Spacer(modifier = Modifier.width(8.dp))
Text(text = "车型 ${orderInfo?.carModel}",
Text(text = "车型 ${orderInfo?.carModel ?: orderInfo?.modelVinNo ?: ""}",
color = Color.Black,
fontSize = 15.sp,
fontWeight = FontWeight.Medium)
@ -106,7 +109,12 @@ fun CarModeView(orderInfo : OrderInfo?) {
Text(text = "点击查看相关资料",
color = Color(0xFFffa500),
fontSize = 14.sp,
fontWeight = FontWeight.Medium)
fontWeight = FontWeight.Medium,
modifier = Modifier.clickable {
val url = AppConfig.getDocmentUrl(keyWord = orderInfo?.carModel
?: orderInfo?.modelVinNo ?: "")
CommonH5Activity.goH5Activity(context = context, url = url, title = "")
})
}
}
Spacer(modifier = Modifier.height(12.dp))

View File

@ -42,6 +42,22 @@
app:layout_constraintStart_toStartOf="parent"
tools:text="请保持面部居中" />
<!-- <TextView-->
<!-- android:id="@+id/lowLightWarning"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_gravity="center"-->
<!-- android:layout_marginTop="20dp"-->
<!-- android:background="#80000000"-->
<!-- android:padding="8dp"-->
<!-- android:text="光线较暗,已自动调高屏幕亮度"-->
<!-- android:textColor="#FFEB3B"-->
<!-- android:textSize="16sp"-->
<!-- android:visibility="gone"-->
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent" />-->
<FrameLayout
android:id="@+id/confirmationLayout"
android:layout_width="match_parent"
@ -63,6 +79,7 @@
android:layout_gravity="center"
android:scaleType="centerCrop" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"