app后台 提现通知

This commit is contained in:
renhaoting 2025-12-29 17:50:01 +08:00
parent 6018362656
commit c36b187f6b
9 changed files with 65 additions and 47 deletions

View File

@ -8,9 +8,7 @@ import java.io.Serializable
data class TaskStateNewBieFirstWithDraw( data class TaskStateNewBieFirstWithDraw(
var rewardGoldNum: Int, var rewardGoldNum: Int,
var hasClaimReward: Boolean = false, var hasClaimReward: Boolean = false,
): Serializable { )
}

View File

@ -5,7 +5,7 @@ minSdk = "24"
targetSdk = "36" targetSdk = "36"
versionCode = "1" versionCode = "1"
versionName = "1.0.0" versionName = "1.0.0"
javaVersion = "17" javaVersion = "11"
#================================Test相关=================================== #================================Test相关===================================
junit = "4.13.2" junit = "4.13.2"
androidx-test-ext-junit = "1.2.1" androidx-test-ext-junit = "1.2.1"

View File

@ -0,0 +1,6 @@
package com.remax.notification
data class TaskStateNewBieFirstWithDraw2(
var rewardGoldNum: Int,
var hasClaimReward: Boolean = false,
)

View File

@ -1,14 +1,14 @@
package com.remax.notification.newUtil package com.remax.notification.newUtil
import android.content.Intent import android.app.PendingIntent
class NotificationConfig(val notificationId: Int = System.currentTimeMillis().toInt(), class NotificationConfig(val notificationId: Int = System.currentTimeMillis().toInt(),
val channelId: String, val channelId: String,
val channelName: String, val channelName: String,
val title: String, val title: String,
val content: String, var content: String,
val smallIcon: Int, val smallIcon: Int,
val intent: Intent? = null, val intent: PendingIntent? = null,
val useFullScreenIntent: Boolean = false, val useFullScreenIntent: Boolean = false,
) { ) {
} }

View File

@ -1,14 +1,27 @@
package com.remax.notification.newUtil package com.remax.notification.newUtil
import android.annotation.SuppressLint
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context
import android.content.Intent import android.content.Intent
import com.ama.core.architecture.BaseApp
import com.ama.core.architecture.util.ResUtil import com.ama.core.architecture.util.ResUtil
import com.remax.notification.R import com.remax.notification.R
import com.remax.notification.builder.LANDING_NOTIFICATION_ACTION
import com.remax.notification.builder.LANDING_NOTIFICATION_FROM
import com.remax.notification.builder.NotificationType
import com.remax.notification.builder.entryPointPendingIntent
import com.remax.notification.builder.type2notificationId
import com.remax.notification.check.NotificationCheckController
import com.remax.notification.config.PushContent
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@SuppressLint("StaticFieldLeak")
object NotificationDatas { object NotificationDatas {
var context: Context = BaseApp.appContext()
// notifi type // notifi type
const val NOTI_TYPE_BG_WITHDRAW = "NOTI_TYPE_BG_WITHDRAW" const val NOTI_TYPE_BG_WITHDRAW = "NOTI_TYPE_BG_WITHDRAW"
const val NOTI_TYPE_BG_RANDOM = "NOTI_TYPE_BG_RANDOM" const val NOTI_TYPE_BG_RANDOM = "NOTI_TYPE_BG_RANDOM"
@ -38,14 +51,20 @@ object NotificationDatas {
init { init {
val bgWithdrawIntent = entryPointPendingIntent(context,
type2notificationId[NotificationType.RESIDENT_WITHDRAW] ?: 0
) {
it.putExtra(LANDING_NOTIFICATION_ACTION, PushContent.ACTION_TYPE_WITHDRAW)
it.putExtra(LANDING_NOTIFICATION_FROM, NotificationCheckController.NotificationType.RESIDENT.string)
}
mConfigList.put(NOTI_TYPE_BG_WITHDRAW, NotificationConfig( mConfigList.put(NOTI_TYPE_BG_WITHDRAW, NotificationConfig(
NOTI_ID_TYPE_BG_WITHDRAW, NOTI_ID_TYPE_BG_WITHDRAW,
CHANNEL_TYPE_BG_WITHDRAW, CHANNEL_TYPE_BG_WITHDRAW,
CHANNEL_TYPE_BG_WITHDRAW_NAME, CHANNEL_TYPE_BG_WITHDRAW_NAME,
ResUtil.getString(R.string.title_bg_withdraw), ResUtil.getString(R.string.title_bg_withdraw),
String.format(ResUtil.getString(R.string.content_bg_withdraw), 50), ResUtil.getString(R.string.content_bg_withdraw),
R.mipmap.icon_bg_withdraw, R.mipmap.icon_bg_withdraw,
null, bgWithdrawIntent,
true, true,
)) ))
} }

View File

@ -26,16 +26,10 @@ class NotificationUtil private constructor() {
} }
} }
} }
private val context = BaseApp.appContext()
private var notificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
/**
* 初始化工具类
*/
fun init(context: Context) {
} private var mContext = BaseApp.appContext()
private var notificationManager: NotificationManager = mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
/** /**
* 创建通知渠道Android 8.0+必需 * 创建通知渠道Android 8.0+必需
@ -64,10 +58,10 @@ class NotificationUtil private constructor() {
notificationId: Int = System.currentTimeMillis().toInt() notificationId: Int = System.currentTimeMillis().toInt()
) { ) {
val pendingIntent = intent?.let { val pendingIntent = intent?.let {
PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_IMMUTABLE) PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
} }
val notification = NotificationCompat.Builder(context, channelId) val notification = NotificationCompat.Builder(mContext, channelId)
.setContentTitle(title) .setContentTitle(title)
.setContentText(content) .setContentText(content)
.setSmallIcon(smallIcon) .setSmallIcon(smallIcon)
@ -92,7 +86,7 @@ class NotificationUtil private constructor() {
notificationId: Int = System.currentTimeMillis().toInt() notificationId: Int = System.currentTimeMillis().toInt()
) { ) {
val pendingIntent = intent?.let { val pendingIntent = intent?.let {
PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_IMMUTABLE) PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
} }
val bigTextStyle = NotificationCompat.BigTextStyle() val bigTextStyle = NotificationCompat.BigTextStyle()
@ -100,7 +94,7 @@ class NotificationUtil private constructor() {
.setBigContentTitle(title) .setBigContentTitle(title)
.setSummaryText(content) .setSummaryText(content)
val notification = NotificationCompat.Builder(context, channelId) val notification = NotificationCompat.Builder(mContext, channelId)
.setStyle(bigTextStyle) .setStyle(bigTextStyle)
.setContentTitle(title) .setContentTitle(title)
.setContentText(content) .setContentText(content)
@ -125,16 +119,16 @@ class NotificationUtil private constructor() {
notificationId: Int = System.currentTimeMillis().toInt() notificationId: Int = System.currentTimeMillis().toInt()
) { ) {
val pendingIntent = intent?.let { val pendingIntent = intent?.let {
PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_IMMUTABLE) PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
} }
val bigPicture = BitmapFactory.decodeResource(context.resources, bigPictureResId) val bigPicture = BitmapFactory.decodeResource(mContext.resources, bigPictureResId)
val bigPictureStyle = NotificationCompat.BigPictureStyle() val bigPictureStyle = NotificationCompat.BigPictureStyle()
.bigPicture(bigPicture) .bigPicture(bigPicture)
.setBigContentTitle(title) .setBigContentTitle(title)
.setSummaryText(content) .setSummaryText(content)
val notification = NotificationCompat.Builder(context, channelId) val notification = NotificationCompat.Builder(mContext, channelId)
.setStyle(bigPictureStyle) .setStyle(bigPictureStyle)
.setContentTitle(title) .setContentTitle(title)
.setContentText(content) .setContentText(content)
@ -159,7 +153,7 @@ class NotificationUtil private constructor() {
indeterminate: Boolean = false, indeterminate: Boolean = false,
notificationId: Int = System.currentTimeMillis().toInt() notificationId: Int = System.currentTimeMillis().toInt()
) { ) {
val notification = NotificationCompat.Builder(context, channelId) val notification = NotificationCompat.Builder(mContext, channelId)
.setContentTitle(title) .setContentTitle(title)
.setContentText(content) .setContentText(content)
.setSmallIcon(smallIcon) .setSmallIcon(smallIcon)
@ -184,10 +178,10 @@ class NotificationUtil private constructor() {
notificationId: Int = System.currentTimeMillis().toInt() notificationId: Int = System.currentTimeMillis().toInt()
) { ) {
val pendingIntent = intent?.let { val pendingIntent = intent?.let {
PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_IMMUTABLE) PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
} }
val builder = NotificationCompat.Builder(context, channelId) val builder = NotificationCompat.Builder(mContext, channelId)
.setContentTitle(title) .setContentTitle(title)
.setContentText(content) .setContentText(content)
.setSmallIcon(smallIcon) .setSmallIcon(smallIcon)
@ -197,7 +191,7 @@ class NotificationUtil private constructor() {
// 添加操作按钮最多3个 // 添加操作按钮最多3个
actions.take(3).forEach { action -> actions.take(3).forEach { action ->
val actionPendingIntent = PendingIntent.getActivity( val actionPendingIntent = PendingIntent.getActivity(
context, mContext,
action.requestCode, action.requestCode,
action.intent, action.intent,
PendingIntent.FLAG_IMMUTABLE PendingIntent.FLAG_IMMUTABLE
@ -220,7 +214,7 @@ class NotificationUtil private constructor() {
notificationId: Int = System.currentTimeMillis().toInt() notificationId: Int = System.currentTimeMillis().toInt()
) { ) {
val pendingIntent = intent?.let { val pendingIntent = intent?.let {
PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_IMMUTABLE) PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
} }
val inboxStyle = NotificationCompat.InboxStyle() val inboxStyle = NotificationCompat.InboxStyle()
@ -231,7 +225,7 @@ class NotificationUtil private constructor() {
inboxStyle.addLine(line) inboxStyle.addLine(line)
} }
val notification = NotificationCompat.Builder(context, channelId) val notification = NotificationCompat.Builder(mContext, channelId)
.setStyle(inboxStyle) .setStyle(inboxStyle)
.setContentTitle(title) .setContentTitle(title)
.setContentText("您有${lines.size}条新消息") .setContentText("您有${lines.size}条新消息")
@ -256,10 +250,10 @@ class NotificationUtil private constructor() {
notificationId: Int = System.currentTimeMillis().toInt() notificationId: Int = System.currentTimeMillis().toInt()
) { ) {
val pendingIntent = intent?.let { val pendingIntent = intent?.let {
PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_IMMUTABLE) PendingIntent.getActivity(mContext, 0, it, PendingIntent.FLAG_IMMUTABLE)
} }
val remoteViews = RemoteViews(context.packageName, layoutResId) val remoteViews = RemoteViews(mContext.packageName, layoutResId)
// 设置自定义视图内容 // 设置自定义视图内容
customViews.forEach { (viewId, value) -> customViews.forEach { (viewId, value) ->
@ -270,7 +264,7 @@ class NotificationUtil private constructor() {
} }
} }
val notification = NotificationCompat.Builder(context, channelId) val notification = NotificationCompat.Builder(mContext, channelId)
.setContent(remoteViews) .setContent(remoteViews)
.setSmallIcon(smallIcon) .setSmallIcon(smallIcon)
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
@ -303,13 +297,13 @@ class NotificationUtil private constructor() {
val title = notifiConfig.title val title = notifiConfig.title
val content = notifiConfig.content val content = notifiConfig.content
val smallIcon = notifiConfig.smallIcon val smallIcon = notifiConfig.smallIcon
val intent = notifiConfig.intent val pendingIntent = notifiConfig.intent
val useFullScreenIntent = notifiConfig.useFullScreenIntent val useFullScreenIntent = notifiConfig.useFullScreenIntent
// 1. 确保初始化 // 1. 确保初始化
val builder = NotificationCompat.Builder(context, channelId) val builder = NotificationCompat.Builder(mContext, channelId)
// 2. 设置通知基本内容 // 2. 设置通知基本内容
builder.setContentTitle(title) builder.setContentTitle(title)
@ -319,9 +313,6 @@ class NotificationUtil private constructor() {
.setWhen(System.currentTimeMillis()) .setWhen(System.currentTimeMillis())
// 3. 处理点击意图 // 3. 处理点击意图
val pendingIntent = intent?.let {
PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_IMMUTABLE)
}
pendingIntent?.let { builder.setContentIntent(it) } pendingIntent?.let { builder.setContentIntent(it) }
// 4. 版本兼容性配置 - 这是触发Heads-up的关键 // 4. 版本兼容性配置 - 这是触发Heads-up的关键
@ -341,13 +332,14 @@ class NotificationUtil private constructor() {
builder.setDefaults(NotificationCompat.DEFAULT_ALL) builder.setDefaults(NotificationCompat.DEFAULT_ALL)
} }
// 5. 可选:全屏意图(用于最高优先级场景) // 5. 可选:全屏意图(用于最高优先级场景)
if (useFullScreenIntent && pendingIntent != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (useFullScreenIntent && pendingIntent != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setFullScreenIntent(pendingIntent, true) builder.setFullScreenIntent(pendingIntent, true)
} }
// 6. 发送通知 // 6. 发送通知
showNotification(notificationId, builder.build(), "name") showNotification(notificationId, builder.build(), "xxxname")
} }
/** /**
@ -424,7 +416,7 @@ class NotificationUtil private constructor() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel(notification.channelId, channelName, NotificationCompat.PRIORITY_HIGH) createNotificationChannel(notification.channelId, channelName, NotificationCompat.PRIORITY_HIGH)
} }
NotificationManagerCompat.from(context).notify(notificationId, notification) NotificationManagerCompat.from(mContext).notify(notificationId, notification)
} }
@ -432,7 +424,7 @@ class NotificationUtil private constructor() {
* 检查通知权限 * 检查通知权限
*/ */
fun isNotificationsEnabled(): Boolean { fun isNotificationsEnabled(): Boolean {
return NotificationManagerCompat.from(context).areNotificationsEnabled() return NotificationManagerCompat.from(mContext).areNotificationsEnabled()
} }
/** /**
@ -450,14 +442,14 @@ class NotificationUtil private constructor() {
* 取消通知 * 取消通知
*/ */
fun cancelNotification(notificationId: Int) { fun cancelNotification(notificationId: Int) {
NotificationManagerCompat.from(context).cancel(notificationId) NotificationManagerCompat.from(mContext).cancel(notificationId)
} }
/** /**
* 取消所有通知 * 取消所有通知
*/ */
fun cancelAllNotifications() { fun cancelAllNotifications() {
NotificationManagerCompat.from(context).cancelAll() NotificationManagerCompat.from(mContext).cancelAll()
} }
/** /**

View File

@ -16,9 +16,10 @@ import androidx.lifecycle.ProcessLifecycleOwner
import androidx.work.PeriodicWorkRequestBuilder import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import androidx.work.workDataOf import androidx.work.workDataOf
import com.ama.core.architecture.util.SpUtil
import com.blankj.utilcode.util.Utils import com.blankj.utilcode.util.Utils
import com.remax.base.report.DataReportManager import com.remax.base.report.DataReportManager
import com.remax.notification.config.NotificationConfigController import com.remax.notification.TaskStateNewBieFirstWithDraw2
import com.remax.notification.controller.NotificationTriggerController import com.remax.notification.controller.NotificationTriggerController
import com.remax.notification.check.NotificationCheckController import com.remax.notification.check.NotificationCheckController
import com.remax.notification.newUtil.NotificationDatas import com.remax.notification.newUtil.NotificationDatas
@ -342,7 +343,9 @@ class NotificationTimingController private constructor() : LifecycleObserver {
private fun showNotifyWithdraw() { private fun showNotifyWithdraw() {
val hasClaimedSmallCash = SpUtil.instance().getObject<TaskStateNewBieFirstWithDraw2>(SpUtil.KEY_NEWBIE_FIRST_WITHDRAW)?.hasClaimReward
NotificationDatas.getConfigForType(NOTI_TYPE_BG_WITHDRAW)?.let { NotificationDatas.getConfigForType(NOTI_TYPE_BG_WITHDRAW)?.let {
it.content = String.format(it.content, if (hasClaimedSmallCash == null || !hasClaimedSmallCash) 0.1 else 50)
NotificationUtil.getInstance().showHeadsUpNotification(it) NotificationUtil.getInstance().showHeadsUpNotification(it)
} }
} }

View File

@ -12,7 +12,7 @@
<!-- new text for notify --> <!-- new text for notify -->
<string name="title_bg_withdraw">Hey there!</string> <string name="title_bg_withdraw">Hey there!</string>
<string name="content_bg_withdraw">Don\'t miss your R$ %d, Tap to withdraw!</string> <string name="content_bg_withdraw">Don\'t miss your R$ %s, Tap to withdraw!</string>
</resources> </resources>

View File

@ -13,7 +13,7 @@
<!-- new text for notify --> <!-- new text for notify -->
<string name="title_bg_withdraw">Olá!</string> <string name="title_bg_withdraw">Olá!</string>
<string name="content_bg_withdraw">Não perca seus R$ %d. Toque para sacar!</string> <string name="content_bg_withdraw">Não perca seus R$ %s. Toque para sacar!</string>