refactor(servicing): 重构推送消息处理机制
- 新增 ZdPushServiceReceive 类用于集中处理推送消息 - 优化了消息处理逻辑,提高了代码的可维护性和可扩展性 -改进了消息在主进程中的广播发送方式 - 优化了语音播放逻辑,提高了播放的稳定性和流畅性 - 调整了通知渠道的创建和通知的发送方式
This commit is contained in:
8
.idea/deploymentTargetSelector.xml
generated
8
.idea/deploymentTargetSelector.xml
generated
@ -4,6 +4,14 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
|
<DropdownSelection timestamp="2025-04-27T03:49:03.966203100Z">
|
||||||
|
<Target type="DEFAULT_BOOT">
|
||||||
|
<handle>
|
||||||
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=4f3d584c" />
|
||||||
|
</handle>
|
||||||
|
</Target>
|
||||||
|
</DropdownSelection>
|
||||||
|
<DialogSelection />
|
||||||
</SelectionState>
|
</SelectionState>
|
||||||
</selectionStates>
|
</selectionStates>
|
||||||
</component>
|
</component>
|
||||||
|
@ -27,7 +27,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.clickable {
|
.clickable {
|
||||||
val uri =
|
val uri =
|
||||||
"zd.assist://app?taskCode=ZD250427100009&driverName=宋志领&driverPhone=17630035658&rescueVehicle=沪88888".toUri()
|
"zd.assist://app?taskCode=ZD250429100095&driverName=宋志领&driverPhone=17630035658&rescueVehicle=沪88888".toUri()
|
||||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ publishing {
|
|||||||
release(MavenPublication) {
|
release(MavenPublication) {
|
||||||
groupId = 'io.github.szl9'
|
groupId = 'io.github.szl9'
|
||||||
artifactId = 'zd_servicing'
|
artifactId = 'zd_servicing'
|
||||||
version = "1.0.1.9.9.25"
|
version = "1.0.1.9.9.31"
|
||||||
|
|
||||||
pom {
|
pom {
|
||||||
packaging = "aar"
|
packaging = "aar"
|
||||||
|
@ -256,6 +256,14 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<receiver
|
||||||
|
android:name="com.za.service.ZdPushServiceReceive"
|
||||||
|
android:exported="false">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.zd.servicing.PUSH_MESSAGE" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name="cn.jpush.android.service.DaemonService"
|
android:name="cn.jpush.android.service.DaemonService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
|
@ -1,130 +1,58 @@
|
|||||||
package com.za.base
|
package com.za.base
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationChannel
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.media.RingtoneManager
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import com.blankj.utilcode.util.ActivityUtils
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.za.base.BaseActivityLifecycleCallbacks.Companion.getCurrentActivity
|
|
||||||
import com.za.bean.JpushBean
|
import com.za.bean.JpushBean
|
||||||
import com.za.common.GlobalData
|
|
||||||
import com.za.common.log.LogUtil
|
import com.za.common.log.LogUtil
|
||||||
import com.za.common.speech.SpeechManager
|
import com.za.service.PushListener
|
||||||
import com.za.servicing.R
|
import com.za.service.ServiceManager
|
||||||
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
import com.za.service.ZdPushServiceReceive
|
||||||
import com.za.ui.view.CommonDialogFragment
|
|
||||||
|
|
||||||
open class PushMessageActivity : AppCompatActivity() {
|
open class PushMessageActivity : AppCompatActivity() {
|
||||||
private var pushMessageReceiver : BroadcastReceiver? = null
|
|
||||||
private var currentDialog : AlertDialog? = null
|
private var currentDialog : AlertDialog? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState : Bundle?) {
|
override fun onCreate(savedInstanceState : Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (! GlobalData.isMaster && pushMessageReceiver == null) {
|
setupPushMessageReceiver()
|
||||||
registerPushMessageReceiver(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerPushMessageReceiver(context : Context) {
|
private fun setupPushMessageReceiver() { // 注册推送消息接收器
|
||||||
pushMessageReceiver = object : BroadcastReceiver() {
|
ServiceManager.registerPushListener(object : PushListener {
|
||||||
override fun onReceive(context : Context?, intent : Intent?) {
|
override fun broadcast(msg : String) {
|
||||||
if (intent?.action == "com.za.rescue.dealer.PUSH_MESSAGE") {
|
sendMessageToMainProcess("broadcast", msg)
|
||||||
val type = intent.getStringExtra("type") ?: return
|
|
||||||
val message = intent.getStringExtra("message") ?: return
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks", "收到来自远程进程的消息: $type")
|
|
||||||
when (type) {
|
|
||||||
"broadcast" -> handleBroadcast("broadcast:$message")
|
|
||||||
"giveUp" -> {
|
|
||||||
try {
|
|
||||||
val jpushBean = Gson().fromJson(message, JpushBean::class.java)
|
|
||||||
val activity =
|
|
||||||
getCurrentActivity() ?: ActivityUtils.getTopActivity()
|
|
||||||
if (activity is AppCompatActivity) {
|
|
||||||
handleGiveUpOrder(activity, jpushBean)
|
|
||||||
}
|
|
||||||
} catch (e : Exception) {
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
|
||||||
"处理订单放弃消息失败: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"importantTip" -> {
|
|
||||||
try {
|
|
||||||
val jpushBean = Gson().fromJson(message, JpushBean::class.java)
|
|
||||||
val activity =
|
|
||||||
getCurrentActivity() ?: ActivityUtils.getTopActivity()
|
|
||||||
if (activity is AppCompatActivity) {
|
|
||||||
handleImportantTip(activity, jpushBean)
|
|
||||||
}
|
|
||||||
} catch (e : Exception) {
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
|
||||||
"处理重要提示消息失败: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"reDispatch" -> {
|
|
||||||
try {
|
|
||||||
val jpushBean = Gson().fromJson(message, JpushBean::class.java)
|
|
||||||
val activity =
|
|
||||||
getCurrentActivity() ?: ActivityUtils.getTopActivity()
|
|
||||||
if (activity is AppCompatActivity) {
|
|
||||||
handleReDispatchOrder(activity, jpushBean)
|
|
||||||
}
|
|
||||||
} catch (e : Exception) {
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
|
||||||
"处理订单重新派发消息失败: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"revoke" -> {
|
|
||||||
try {
|
|
||||||
handleRevokeOrder()
|
|
||||||
} catch (e : Exception) {
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
|
||||||
"处理订单撤回消息失败: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ContextCompat.registerReceiver(context,
|
override fun giveUpOrder(jpushBean : JpushBean) {
|
||||||
pushMessageReceiver,
|
sendMessageToMainProcess("giveUp", Gson().toJson(jpushBean))
|
||||||
IntentFilter("com.za.rescue.dealer.PUSH_MESSAGE"),
|
|
||||||
ContextCompat.RECEIVER_NOT_EXPORTED)
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks", "注册推送消息接收器")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
if (isLastActivity()) {
|
|
||||||
try {
|
|
||||||
this.unregisterReceiver(pushMessageReceiver)
|
|
||||||
pushMessageReceiver = null
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks", "注销推送消息接收器")
|
|
||||||
} catch (e : Exception) {
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks",
|
|
||||||
"注销推送消息接收器失败: ${e.message}")
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
override fun importantTip(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("importantTip", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newOrderMsg(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("newOrder", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reDispatchOrder(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("reDispatch", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun revokeOrder(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("revoke", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isLastActivity() : Boolean { // 检查是否是最后一个活动的Activity
|
private fun sendMessageToMainProcess(type : String, message : String) { // 使用广播将消息发送到主进程
|
||||||
return ActivityUtils.getActivityList().size <= 1
|
val intent = Intent(ZdPushServiceReceive.RECEIVE_ACTION).setPackage(packageName)
|
||||||
|
intent.putExtra("type", type)
|
||||||
|
intent.putExtra("message", message)
|
||||||
|
sendBroadcast(intent)
|
||||||
|
LogUtil.print("KeepAliveService", "发送消息到主进程: $type")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
@ -132,18 +60,6 @@ open class PushMessageActivity : AppCompatActivity() {
|
|||||||
dismissCurrentDialog()
|
dismissCurrentDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle broadcast messages
|
|
||||||
private fun handleBroadcast(msg : String) {
|
|
||||||
try {
|
|
||||||
val content = msg.substring(10)
|
|
||||||
sendNotification(GlobalData.application, content)
|
|
||||||
LogUtil.print("JpushMessage", "Broadcast content: $content")
|
|
||||||
} catch (e : Exception) {
|
|
||||||
LogUtil.print("JpushMessage", "Broadcast failed: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun dismissCurrentDialog() {
|
private fun dismissCurrentDialog() {
|
||||||
try {
|
try {
|
||||||
currentDialog?.dismiss()
|
currentDialog?.dismiss()
|
||||||
@ -153,116 +69,6 @@ open class PushMessageActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleGiveUpOrder(activity : AppCompatActivity,
|
|
||||||
jpushBean : JpushBean) { // 播放提示音
|
|
||||||
playNotificationSound(this)
|
|
||||||
|
|
||||||
if (GlobalData.currentOrder != null && GlobalData.currentOrder?.taskId == jpushBean.taskId) {
|
|
||||||
SpeechManager.playCurrentOrderCanceled()
|
|
||||||
CommonDialogFragment(title = "订单放弃",
|
|
||||||
message = buildGiveUpMessage(jpushBean),
|
|
||||||
confirmText = "去拍照",
|
|
||||||
cancelText = "我已了解",
|
|
||||||
confirm = {
|
|
||||||
OrderGiveUpActivity.goOrderGiveUpActivity(this,
|
|
||||||
giveUpType = GIVE_UP_TYPE_NORMAL,
|
|
||||||
taskId = jpushBean.taskId)
|
|
||||||
}).show(this.supportFragmentManager, DIALOG_TAG_GIVE_UP)
|
|
||||||
} else {
|
|
||||||
SpeechManager.playOrderCanceled()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleRevokeOrder() {
|
|
||||||
playNotificationSound(this)
|
|
||||||
SpeechManager.speech("订单被撤回") // 获取当前Activity进行处理
|
|
||||||
this.finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleReDispatchOrder(activity : AppCompatActivity, jpushBean : JpushBean) {
|
|
||||||
playNotificationSound(this)
|
|
||||||
currentDialog = AlertDialog.Builder(this).setTitle("订单重新派发")
|
|
||||||
.setMessage(buildReDispatchMessage(jpushBean)).setCancelable(false)
|
|
||||||
.setPositiveButton("确定") { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleImportantTip(activity : AppCompatActivity, jpushBean : JpushBean) {
|
|
||||||
playNotificationSound(this)
|
|
||||||
SpeechManager.speech("重要提醒:${jpushBean.tipContent ?: ""}")
|
|
||||||
currentDialog =
|
|
||||||
AlertDialog.Builder(this).setTitle("重要提醒").setMessage(jpushBean.tipContent)
|
|
||||||
.setNegativeButton("我已了解") { dialog : DialogInterface, _ : Int -> dialog.dismiss() }
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildGiveUpMessage(jpushBean : JpushBean) : String {
|
|
||||||
return buildString {
|
|
||||||
append("该工单已放弃")
|
|
||||||
jpushBean.taskCode?.let { append("\n\n订单号:$it") }
|
|
||||||
jpushBean.address?.let { append("\n地址:$it") }
|
|
||||||
append("\n\n是否需要拍放空照片?")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildReDispatchMessage(jpushBean : JpushBean) : String {
|
|
||||||
return buildString {
|
|
||||||
append("该订单已重新派发")
|
|
||||||
jpushBean.taskCode?.let { append("\n\n订单号:$it") }
|
|
||||||
jpushBean.address?.let { append("\n地址:$it") }
|
|
||||||
jpushBean.addressRemark?.let {
|
|
||||||
if (it.isNotBlank()) {
|
|
||||||
append("\n\n备注:$it")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun playNotificationSound(activity : Activity) {
|
|
||||||
try {
|
|
||||||
val notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
|
||||||
RingtoneManager.getRingtone(activity, notification)?.play()
|
|
||||||
} catch (e : Exception) {
|
|
||||||
LogUtil.print("PushActivityLifecycleCallbacks", "播放提示音失败: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val CHANNEL_ID = "ImportantMessagesChannel"
|
|
||||||
private val NOTIFICATION_ID = 1003
|
|
||||||
|
|
||||||
// Initialize notification channel
|
|
||||||
private fun createNotificationChannel(context : Context) {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
val channel = NotificationChannel(CHANNEL_ID,
|
|
||||||
"订单通知",
|
|
||||||
NotificationManager.IMPORTANCE_HIGH).apply {
|
|
||||||
description = "用于接收重要消息通知"
|
|
||||||
setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
|
|
||||||
Notification.AUDIO_ATTRIBUTES_DEFAULT)
|
|
||||||
enableVibration(true)
|
|
||||||
}
|
|
||||||
val notificationManager =
|
|
||||||
context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
notificationManager.createNotificationChannel(channel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send notification
|
|
||||||
private fun sendNotification(context : Context, message : String) {
|
|
||||||
createNotificationChannel(context)
|
|
||||||
val notification =
|
|
||||||
NotificationCompat.Builder(context, CHANNEL_ID).setContentTitle("重要通知")
|
|
||||||
.setContentText(message).setSmallIcon(R.mipmap.ic_launcher) // 替换为你的应用图标
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH).setAutoCancel(true) // 点击后自动取消通知
|
|
||||||
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
|
|
||||||
.setVibrate(longArrayOf(0, 100, 200, 300)).build()
|
|
||||||
|
|
||||||
val notificationManager =
|
|
||||||
context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
notificationManager.notify(NOTIFICATION_ID, notification)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal const val GIVE_UP_TYPE_NORMAL = 1
|
internal const val GIVE_UP_TYPE_NORMAL = 1
|
||||||
internal const val DIALOG_TAG_GIVE_UP = "giveUp"
|
internal const val DIALOG_TAG_GIVE_UP = "giveUp"
|
||||||
|
@ -95,10 +95,11 @@ object GlobalData : GlobalLocalData() {
|
|||||||
|
|
||||||
var currentLocation : AMapLocation? = null
|
var currentLocation : AMapLocation? = null
|
||||||
get() {
|
get() {
|
||||||
return field
|
return mmkv.decodeParcelable("currentLocation", AMapLocation::class.java)
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
value?.time = System.currentTimeMillis()
|
value?.time= System.currentTimeMillis()
|
||||||
|
mmkv.encode("currentLocation", value)
|
||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ object GlobalData : GlobalLocalData() {
|
|||||||
currentLocation = null
|
currentLocation = null
|
||||||
driverInfoBean = null
|
driverInfoBean = null
|
||||||
loginTime = null
|
loginTime = null
|
||||||
// isLoginRecognition = null
|
isLoginRecognition = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearAllOrderCache() {
|
fun clearAllOrderCache() {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.za.common.speech
|
package com.za.common.speech
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.media.AudioAttributes
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.media.MediaPlayer
|
import android.media.MediaPlayer
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.blankj.utilcode.util.ThreadUtils
|
|
||||||
import com.za.base.AppConfig
|
import com.za.base.AppConfig
|
||||||
import com.za.bean.request.AppNewOrderVoiceRequest
|
import com.za.bean.request.AppNewOrderVoiceRequest
|
||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
@ -16,7 +16,11 @@ import com.za.room.db.user.LocalResourceBean
|
|||||||
import com.za.servicing.R
|
import com.za.servicing.R
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
import kotlin.concurrent.thread
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
object SpeechManager {
|
object SpeechManager {
|
||||||
private var mContext : Application? = null
|
private var mContext : Application? = null
|
||||||
@ -65,6 +69,7 @@ object SpeechManager {
|
|||||||
}
|
}
|
||||||
val audioManager =
|
val audioManager =
|
||||||
ContextCompat.getSystemService(GlobalData.application, AudioManager::class.java)
|
ContextCompat.getSystemService(GlobalData.application, AudioManager::class.java)
|
||||||
|
originVolume = audioManager?.getStreamVolume(AudioManager.STREAM_MUSIC) ?: 0
|
||||||
val maxVolume = audioManager?.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
val maxVolume = audioManager?.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||||
audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC,
|
audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC,
|
||||||
maxVolume ?: 1,
|
maxVolume ?: 1,
|
||||||
@ -127,60 +132,89 @@ object SpeechManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun playNewOrder() {
|
private fun playNewOrder() {
|
||||||
stopPlayMedia()
|
try { // 先释放之前的MediaPlayer实例,避免资源泄漏
|
||||||
setMaxAudioVolume()
|
releaseMediaPlayer()
|
||||||
mediaPlayer = MediaPlayer.create(mContext, R.raw.neworder)
|
|
||||||
mediaPlayer?.start()
|
// 创建新的MediaPlayer实例
|
||||||
mediaPlayer?.setOnCompletionListener {
|
mediaPlayer = MediaPlayer.create(GlobalData.application, R.raw.neworder)
|
||||||
resetAudioVolume()
|
mediaPlayer?.setOnCompletionListener { // 播放完成后释放资源
|
||||||
|
releaseMediaPlayer()
|
||||||
|
}
|
||||||
|
mediaPlayer?.setOnErrorListener { mp, what, extra ->
|
||||||
|
LogUtil.print("playNewOrder", "MediaPlayer错误: what=$what, extra=$extra")
|
||||||
|
releaseMediaPlayer()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置最大音量
|
||||||
|
setMaxAudioVolume()
|
||||||
|
|
||||||
|
// 开始播放
|
||||||
|
mediaPlayer?.start()
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("playNewOrder", "播放出错: ${e.message}")
|
||||||
|
releaseMediaPlayer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun playNewOrderFromNet(url : String) {
|
private fun playNewOrderFromNet(url : String) {
|
||||||
try {
|
try { // 先释放之前的MediaPlayer实例
|
||||||
stopPlayMedia()
|
LogUtil.print("playNewOrderFromNet", "播放新订单语音: $url")
|
||||||
setMaxAudioVolume()
|
releaseMediaPlayer() // 创建新的MediaPlayer实例
|
||||||
mediaPlayer = MediaPlayer()
|
mediaPlayer = MediaPlayer()
|
||||||
mediaPlayer?.setAudioStreamType(AudioManager.STREAM_MUSIC) // 设置音频流类型
|
mediaPlayer?.setAudioAttributes(AudioAttributes.Builder()
|
||||||
mediaPlayer?.setDataSource(url) // 设置音频文件的 URL
|
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||||
mediaPlayer?.prepareAsync() // 异步准备音频
|
.setUsage(AudioAttributes.USAGE_MEDIA).build())
|
||||||
// 准备完成后开始播放
|
|
||||||
mediaPlayer?.setOnPreparedListener { obj : MediaPlayer -> obj.start() }
|
mediaPlayer?.setDataSource(url)
|
||||||
mediaPlayer?.setOnErrorListener { mp : MediaPlayer?, what : Int, extra : Int ->
|
mediaPlayer?.setOnPreparedListener { // 设置最大音量
|
||||||
playNewOrder()
|
setMaxAudioVolume() // 准备完成后开始播放
|
||||||
false
|
it.start()
|
||||||
}
|
}
|
||||||
mediaPlayer?.setOnCompletionListener {
|
mediaPlayer?.setOnCompletionListener { // 播放完成后释放资源
|
||||||
resetAudioVolume()
|
releaseMediaPlayer()
|
||||||
}
|
}
|
||||||
|
mediaPlayer?.setOnErrorListener { mp, what, extra ->
|
||||||
|
LogUtil.print("playNewOrderFromNet", "MediaPlayer错误: what=$what, extra=$extra")
|
||||||
|
releaseMediaPlayer()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步准备,避免阻塞UI线程
|
||||||
|
mediaPlayer?.prepareAsync()
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
playNewOrder()
|
LogUtil.print("playNewOrderFromNet", "播放出错: ${e.message}")
|
||||||
LogUtil.print("播放新订单失败", e)
|
releaseMediaPlayer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopPlayMedia() {
|
// 安全释放MediaPlayer资源
|
||||||
ThreadUtils.runOnUiThread {
|
fun releaseMediaPlayer() {
|
||||||
if (null != mediaPlayer) {
|
try {
|
||||||
mediaPlayer?.stop()
|
mediaPlayer?.let {
|
||||||
mediaPlayer?.release()
|
if (it.isPlaying) {
|
||||||
mediaPlayer = null
|
it.stop()
|
||||||
|
}
|
||||||
|
it.reset()
|
||||||
|
it.release()
|
||||||
}
|
}
|
||||||
|
mediaPlayer = null // 恢复原始音量
|
||||||
|
resetAudioVolume()
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("releaseMediaPlayer", "释放MediaPlayer出错: ${e.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun speechNewOrderSound(content : String?) {
|
fun speechNewOrderSound(content : String?) {
|
||||||
if (content.isNullOrBlank()) {
|
if (content.isNullOrBlank()) {
|
||||||
speechNewOrderLooper("您有新的中道救援订单,请尽快接单!") { playNewOrder() }
|
speechNewOrderLocalSoundLooper()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val localResourceDao = RoomHelper.db?.localResourceDao()
|
val localResourceDao = RoomHelper.db?.localResourceDao()
|
||||||
val localUrlResource = localResourceDao?.getLocalResourceByName(content)
|
val localUrlResource = localResourceDao?.getLocalResourceByName(content)
|
||||||
if (localUrlResource != null && ! localUrlResource.resourceUrl.isNullOrBlank()) {
|
if (localUrlResource != null && ! localUrlResource.resourceUrl.isNullOrBlank()) {
|
||||||
speechNewOrderLooper(content) {
|
speechNewOrderNetLooper(content, localUrlResource.resourceUrl ?: "")
|
||||||
playNewOrderFromNet(localUrlResource.resourceUrl)
|
|
||||||
}
|
|
||||||
LogUtil.print("handlerNewOrderVoice", "播放本地语音");
|
LogUtil.print("handlerNewOrderVoice", "播放本地语音");
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -191,28 +225,59 @@ object SpeechManager {
|
|||||||
.subscribe(object : BaseObserver<String>() {
|
.subscribe(object : BaseObserver<String>() {
|
||||||
override fun doSuccess(it : String?) {
|
override fun doSuccess(it : String?) {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
speechNewOrderLooper(content) { playNewOrder() }
|
speechNewOrderLocalSoundLooper()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
localResourceDao?.insert(LocalResourceBean(resourceName = content,
|
localResourceDao?.insert(LocalResourceBean(resourceName = content,
|
||||||
resourceType = 1,
|
resourceType = 1,
|
||||||
resourceUrl = it))
|
resourceUrl = it))
|
||||||
speechNewOrderLooper(content) { playNewOrderFromNet(it) }
|
speechNewOrderNetLooper(content, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doFailure(code : Int, msg : String?) {
|
override fun doFailure(code : Int, msg : String?) {
|
||||||
speechNewOrderLooper("您有新的中道救援订单,请尽快接单!") { playNewOrder() }
|
speechNewOrderLocalSoundLooper()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun speechNewOrderLooper(content : String, play : () -> Unit) {
|
|
||||||
thread {
|
private fun speechNewOrderLocalSoundLooper() {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
while (System.currentTimeMillis() - startTime < 1000 * 60 * 3 && GlobalData.isHandlerNewOrder == false) {
|
while (System.currentTimeMillis() - startTime < 1000 * 60 * 3 && GlobalData.isHandlerNewOrder == false) {
|
||||||
play()
|
try {
|
||||||
Thread.sleep(250L * content.length)
|
delay(250L * "您有新的中道救援订单,请尽快接单!".length)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
playNewOrder()
|
||||||
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("speechNewOrderLooper",
|
||||||
|
"播放循环出错: ${e.message}") // 出错时也要等待一下,避免无限循环
|
||||||
|
delay(1000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
GlobalData.isHandlerNewOrder = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun speechNewOrderNetLooper(content : String, url : String) {
|
||||||
|
val url = url.replace("http://", "https://")
|
||||||
|
GlobalData.isHandlerNewOrder = false
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
while (System.currentTimeMillis() - startTime < 1000 * 60 * 3 && GlobalData.isHandlerNewOrder == false) {
|
||||||
|
try {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
playNewOrderFromNet(url)
|
||||||
|
}
|
||||||
|
delay(250L * content.length)
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("speechNewOrderLooper",
|
||||||
|
"播放循环出错: ${e.message}") // 出错时也要等待一下,避免无限循环
|
||||||
|
delay(1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GlobalData.isHandlerNewOrder = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -30,7 +30,7 @@ interface PushListener {
|
|||||||
fun importantTip(jpushBean : JpushBean)
|
fun importantTip(jpushBean : JpushBean)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class LastJPushBean(val msg : Int, val time : Long = System.nanoTime())
|
data class LastJPushBean(val msg : String, val time : Long = System.currentTimeMillis())
|
||||||
|
|
||||||
object ServiceManager {
|
object ServiceManager {
|
||||||
@Volatile
|
@Volatile
|
||||||
@ -115,21 +115,21 @@ object ServiceManager {
|
|||||||
|
|
||||||
// 优化后的重复消息判断
|
// 优化后的重复消息判断
|
||||||
lastJPushBean?.let {
|
lastJPushBean?.let {
|
||||||
if (System.nanoTime() - it.time < DUPLICATE_MSG_THRESHOLD && it.msg == msg.hashCode()) {
|
if (System.currentTimeMillis() - it.time < DUPLICATE_MSG_THRESHOLD && it.msg == msg) {
|
||||||
LogUtil.print("MessageHandler", "Duplicate message detected (hash: ${msg})")
|
LogUtil.print("MessageHandler", "Duplicate message detected (hash: ${msg})")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.startsWith("broadcast:")) {
|
if (msg.startsWith("broadcast:")) {
|
||||||
lastJPushBean = LastJPushBean(msg = msg.hashCode())
|
lastJPushBean = LastJPushBean(msg = msg)
|
||||||
handleBroadcast(msg) // PushMessageLiveData.postPushMessage(msg)
|
handleBroadcast(msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
lastJPushBean = LastJPushBean(msg = msg.hashCode())
|
lastJPushBean = LastJPushBean(msg = msg)
|
||||||
val jpushOrderInfoBean = Gson().fromJson(msg, JpushBean::class.java)
|
val jpushOrderInfoBean = Gson().fromJson(msg, JpushBean::class.java)
|
||||||
sendSystemNotificationFromMessage(jpushOrderInfoBean) // PushMessageLiveData.postPushMessage(msg)
|
sendSystemNotificationFromMessage(jpushOrderInfoBean)
|
||||||
when (jpushOrderInfoBean.pushType) {
|
when (jpushOrderInfoBean.pushType) {
|
||||||
0 -> newOrderMsg(jpushOrderInfoBean)
|
0 -> newOrderMsg(jpushOrderInfoBean)
|
||||||
1 -> handleTypeOneMessage(jpushOrderInfoBean)
|
1 -> handleTypeOneMessage(jpushOrderInfoBean)
|
||||||
@ -138,7 +138,7 @@ object ServiceManager {
|
|||||||
"Unknown push type: ${jpushOrderInfoBean.pushType}")
|
"Unknown push type: ${jpushOrderInfoBean.pushType}")
|
||||||
}
|
}
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
if (msg.startsWith("broadcast:")) { // PushMessageLiveData.postPushMessage(msg)
|
if (msg.startsWith("broadcast:")) {
|
||||||
handleBroadcast(msg)
|
handleBroadcast(msg)
|
||||||
}
|
}
|
||||||
LogUtil.print("JpushMessage", "Error handling message: ${e.message}")
|
LogUtil.print("JpushMessage", "Error handling message: ${e.message}")
|
||||||
|
237
servicing/src/main/java/com/za/service/ZdPushServiceReceive.kt
Normal file
237
servicing/src/main/java/com/za/service/ZdPushServiceReceive.kt
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
package com.za.service
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.app.Notification
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.content.Intent
|
||||||
|
import android.media.RingtoneManager
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import com.blankj.utilcode.util.ActivityUtils
|
||||||
|
import com.blankj.utilcode.util.AppUtils
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.za.base.BaseActivityLifecycleCallbacks
|
||||||
|
import com.za.bean.JpushBean
|
||||||
|
import com.za.common.GlobalData
|
||||||
|
import com.za.common.log.LogUtil
|
||||||
|
import com.za.common.speech.SpeechManager
|
||||||
|
import com.za.servicing.R
|
||||||
|
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
|
||||||
|
import com.za.ui.view.CommonDialogFragment
|
||||||
|
|
||||||
|
class ZdPushServiceReceive : BroadcastReceiver() {
|
||||||
|
companion object {
|
||||||
|
const val RECEIVE_ACTION = "com.zd.servicing.PUSH_MESSAGE"
|
||||||
|
private const val GIVE_UP_TYPE_NORMAL = 1
|
||||||
|
private const val DIALOG_TAG_GIVE_UP = "giveUp"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlerMessage(context : Context?, intent : Intent?) {
|
||||||
|
val activity = context ?: ActivityUtils.getTopActivity()
|
||||||
|
activity as? AppCompatActivity
|
||||||
|
if (intent?.action == RECEIVE_ACTION) {
|
||||||
|
val type = intent.getStringExtra("type") ?: return
|
||||||
|
val message = intent.getStringExtra("message") ?: return
|
||||||
|
if (ActivityUtils.getTopActivity() == null) {
|
||||||
|
AppUtils.launchApp(GlobalData.application.packageName)
|
||||||
|
}
|
||||||
|
LogUtil.print("PushActivityLifecycleCallbacks", "收到来自远程进程的消息: $type")
|
||||||
|
when (type) {
|
||||||
|
"broadcast" -> handleBroadcast("broadcast:$message")
|
||||||
|
|
||||||
|
"giveUp" -> {
|
||||||
|
try {
|
||||||
|
val jpushBean = Gson().fromJson(message, JpushBean::class.java)
|
||||||
|
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
|
||||||
|
?: ActivityUtils.getTopActivity()
|
||||||
|
if (activity is AppCompatActivity) {
|
||||||
|
handleGiveUpOrder(activity, jpushBean)
|
||||||
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||||
|
"处理订单放弃消息失败: ${e.message}")
|
||||||
|
}
|
||||||
|
} // 处理其他类型的消息...
|
||||||
|
"importantTip" -> {
|
||||||
|
try {
|
||||||
|
val jpushBean = Gson().fromJson(message, JpushBean::class.java)
|
||||||
|
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
|
||||||
|
?: ActivityUtils.getTopActivity()
|
||||||
|
if (activity is AppCompatActivity) {
|
||||||
|
handleImportantTip(activity, jpushBean)
|
||||||
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||||
|
"处理重要提示消息失败: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"reDispatch" -> {
|
||||||
|
try {
|
||||||
|
val jpushBean = Gson().fromJson(message, JpushBean::class.java)
|
||||||
|
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
|
||||||
|
?: ActivityUtils.getTopActivity()
|
||||||
|
if (activity is AppCompatActivity) {
|
||||||
|
handleReDispatchOrder(activity, jpushBean)
|
||||||
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||||
|
"处理订单重新派发消息失败: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"revoke" -> {
|
||||||
|
try {
|
||||||
|
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
|
||||||
|
?: ActivityUtils.getTopActivity()
|
||||||
|
if (activity is AppCompatActivity) {
|
||||||
|
handleRevokeOrder(activity)
|
||||||
|
}
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("PushActivityLifecycleCallbacks",
|
||||||
|
"处理订单撤回消息失败: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleGiveUpOrder(activity : Activity, jpushBean : JpushBean) {
|
||||||
|
if (activity !is AppCompatActivity) return
|
||||||
|
|
||||||
|
// 播放提示音
|
||||||
|
playNotificationSound(activity)
|
||||||
|
|
||||||
|
if (GlobalData.currentOrder != null && GlobalData.currentOrder?.taskId == jpushBean.taskId) {
|
||||||
|
SpeechManager.playCurrentOrderCanceled()
|
||||||
|
CommonDialogFragment(title = "订单放弃",
|
||||||
|
message = buildGiveUpMessage(jpushBean),
|
||||||
|
confirmText = "去拍照",
|
||||||
|
cancelText = "我已了解",
|
||||||
|
confirm = {
|
||||||
|
OrderGiveUpActivity.Companion.goOrderGiveUpActivity(activity,
|
||||||
|
giveUpType = GIVE_UP_TYPE_NORMAL,
|
||||||
|
taskId = jpushBean.taskId)
|
||||||
|
}).show(activity.supportFragmentManager, DIALOG_TAG_GIVE_UP)
|
||||||
|
} else {
|
||||||
|
SpeechManager.playOrderCanceled()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleRevokeOrder(activity : Activity) {
|
||||||
|
playNotificationSound(activity)
|
||||||
|
SpeechManager.speech("订单被撤回")
|
||||||
|
ActivityUtils.getTopActivity().finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleReDispatchOrder(activity : Activity, jpushBean : JpushBean) {
|
||||||
|
playNotificationSound(activity)
|
||||||
|
BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()?.let { currentActivity ->
|
||||||
|
if (currentActivity is AppCompatActivity) {
|
||||||
|
AlertDialog.Builder(currentActivity).setTitle("订单重新派发")
|
||||||
|
.setMessage(buildReDispatchMessage(jpushBean)).setCancelable(false)
|
||||||
|
.setPositiveButton("确定") { dialog, _ ->
|
||||||
|
dialog.dismiss()
|
||||||
|
currentActivity.finish()
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleImportantTip(activity : Activity, jpushBean : JpushBean) {
|
||||||
|
playNotificationSound(activity)
|
||||||
|
SpeechManager.speech("重要提醒:${jpushBean.tipContent ?: ""}")
|
||||||
|
AlertDialog.Builder(activity).setTitle("重要提醒").setMessage(jpushBean.tipContent)
|
||||||
|
.setNegativeButton("我已了解") { dialog : DialogInterface, _ : Int -> dialog.dismiss() }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle broadcast messages
|
||||||
|
private fun handleBroadcast(msg : String) {
|
||||||
|
try {
|
||||||
|
val content = msg.substring(10)
|
||||||
|
sendNotification(GlobalData.application, content)
|
||||||
|
LogUtil.print("JpushMessage", "Broadcast content: $content")
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("JpushMessage", "Broadcast failed: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildReDispatchMessage(jpushBean : JpushBean) : String {
|
||||||
|
return buildString {
|
||||||
|
append("该订单已重新派发")
|
||||||
|
jpushBean.taskCode?.let { append("\n\n订单号:$it") }
|
||||||
|
jpushBean.address?.let { append("\n地址:$it") }
|
||||||
|
jpushBean.addressRemark?.let {
|
||||||
|
if (it.isNotBlank()) {
|
||||||
|
append("\n\n备注:$it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun buildGiveUpMessage(jpushBean : JpushBean) : String {
|
||||||
|
return buildString {
|
||||||
|
append("该工单已放弃")
|
||||||
|
jpushBean.taskCode?.let { append("\n\n订单号:$it") }
|
||||||
|
jpushBean.address?.let { append("\n地址:$it") }
|
||||||
|
append("\n\n是否需要拍放空照片?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun playNotificationSound(activity : Activity?) {
|
||||||
|
try {
|
||||||
|
val notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
||||||
|
RingtoneManager.getRingtone(activity, notification)?.play()
|
||||||
|
} catch (e : Exception) {
|
||||||
|
LogUtil.print("PushActivityLifecycleCallbacks", "播放提示音失败: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val CHANNEL_ID = "ImportantMessagesChannel"
|
||||||
|
private val NOTIFICATION_ID = 1003
|
||||||
|
|
||||||
|
// Initialize notification channel
|
||||||
|
private fun createNotificationChannel(context : Context) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val channel = NotificationChannel(CHANNEL_ID,
|
||||||
|
"订单通知",
|
||||||
|
NotificationManager.IMPORTANCE_HIGH).apply {
|
||||||
|
description = "用于接收重要消息通知"
|
||||||
|
setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
|
||||||
|
Notification.AUDIO_ATTRIBUTES_DEFAULT)
|
||||||
|
enableVibration(true)
|
||||||
|
}
|
||||||
|
val notificationManager =
|
||||||
|
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
notificationManager.createNotificationChannel(channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send notification
|
||||||
|
private fun sendNotification(context : Context, message : String) {
|
||||||
|
createNotificationChannel(context)
|
||||||
|
val notification =
|
||||||
|
NotificationCompat.Builder(context, CHANNEL_ID).setContentTitle("重要通知")
|
||||||
|
.setContentText(message).setSmallIcon(R.mipmap.ic_launcher) // 替换为你的应用图标
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH).setAutoCancel(true) // 点击后自动取消通知
|
||||||
|
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
|
||||||
|
.setVibrate(longArrayOf(0, 100, 200, 300)).build()
|
||||||
|
|
||||||
|
val notificationManager =
|
||||||
|
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
notificationManager.notify(NOTIFICATION_ID, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceive(context : Context?, intent : Intent?) {
|
||||||
|
handlerMessage(context, intent)
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ class ConnectionOptionWrapper(
|
|||||||
*/
|
*/
|
||||||
@JvmField
|
@JvmField
|
||||||
val mqttConnectOptions: MqttConnectOptions = MqttConnectOptions().apply {
|
val mqttConnectOptions: MqttConnectOptions = MqttConnectOptions().apply {
|
||||||
isCleanSession = false
|
isCleanSession = true
|
||||||
keepAliveInterval = 90 // Keep alive interval in seconds
|
keepAliveInterval = 90 // Keep alive interval in seconds
|
||||||
isAutomaticReconnect = true
|
isAutomaticReconnect = true
|
||||||
mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1
|
mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1
|
||||||
|
@ -46,20 +46,25 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.blankj.utilcode.util.ActivityUtils
|
import com.blankj.utilcode.util.ActivityUtils
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.za.base.BaseActivity
|
import com.za.base.BaseActivity
|
||||||
import com.za.base.theme.bgColor
|
import com.za.base.theme.bgColor
|
||||||
import com.za.base.view.CommonButton
|
import com.za.base.view.CommonButton
|
||||||
import com.za.base.view.EmptyView
|
import com.za.base.view.EmptyView
|
||||||
import com.za.base.view.HeadView
|
import com.za.base.view.HeadView
|
||||||
import com.za.base.view.LoadError
|
import com.za.base.view.LoadError
|
||||||
|
import com.za.bean.JpushBean
|
||||||
import com.za.bean.db.order.OrderInfo
|
import com.za.bean.db.order.OrderInfo
|
||||||
import com.za.common.GlobalData
|
import com.za.common.GlobalData
|
||||||
|
import com.za.common.log.LogUtil
|
||||||
import com.za.common.util.DeviceUtil
|
import com.za.common.util.DeviceUtil
|
||||||
import com.za.ext.convertToFlowName
|
import com.za.ext.convertToFlowName
|
||||||
import com.za.ext.copy
|
import com.za.ext.copy
|
||||||
import com.za.ext.finish
|
import com.za.ext.finish
|
||||||
import com.za.ext.goStatusPage
|
import com.za.ext.goStatusPage
|
||||||
|
import com.za.service.PushListener
|
||||||
import com.za.service.ServiceManager
|
import com.za.service.ServiceManager
|
||||||
|
import com.za.service.ZdPushServiceReceive
|
||||||
import com.za.service.location.ZdLocationManager
|
import com.za.service.location.ZdLocationManager
|
||||||
import com.za.servicing.R
|
import com.za.servicing.R
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -77,6 +82,47 @@ class ServicingMainActivity : BaseActivity() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
setupPushMessageReceiver()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupPushMessageReceiver() { // 注册推送消息接收器
|
||||||
|
ServiceManager.registerPushListener(object : PushListener {
|
||||||
|
override fun broadcast(msg : String) {
|
||||||
|
sendMessageToMainProcess("broadcast", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun giveUpOrder(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("giveUp", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun importantTip(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("importantTip", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newOrderMsg(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("newOrder", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reDispatchOrder(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("reDispatch", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun revokeOrder(jpushBean : JpushBean) {
|
||||||
|
sendMessageToMainProcess("revoke", Gson().toJson(jpushBean))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendMessageToMainProcess(type : String, message : String) { // 使用广播将消息发送到主进程
|
||||||
|
val intent = Intent(ZdPushServiceReceive.RECEIVE_ACTION).setPackage(packageName)
|
||||||
|
intent.putExtra("type", type)
|
||||||
|
intent.putExtra("message", message)
|
||||||
|
sendBroadcast(intent)
|
||||||
|
LogUtil.print(TAG, "发送消息到主进程: $type")
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun goToMain(context : Context,
|
fun goToMain(context : Context,
|
||||||
driverName : String? = null,
|
driverName : String? = null,
|
||||||
@ -116,6 +162,7 @@ private fun ServicingMainScreen(jobCode : String? = null,
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
ServiceManager.initialize(GlobalData.application)
|
ServiceManager.initialize(GlobalData.application)
|
||||||
ZdLocationManager.startContinuousLocation(GlobalData.application)
|
ZdLocationManager.startContinuousLocation(GlobalData.application)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
|
|||||||
userOrderId = userOrderId,
|
userOrderId = userOrderId,
|
||||||
taskId = taskId,
|
taskId = taskId,
|
||||||
unitPrice = it?.unitPrice,
|
unitPrice = it?.unitPrice,
|
||||||
mileage = it?.amount,
|
mileage = it?.mileage,
|
||||||
mileageText = "${it?.mileage ?: ""}",
|
mileageText = "${it?.mileage ?: ""}",
|
||||||
calculateAmount = it?.calculateAmount,
|
calculateAmount = it?.calculateAmount,
|
||||||
adjustAmount = it?.adjustAmount?.toFloat(),
|
adjustAmount = it?.adjustAmount?.toFloat(),
|
||||||
|
Reference in New Issue
Block a user