package com.gamedog.vididin.manager import android.Manifest import android.app.Activity import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.os.Build import android.provider.Settings import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.lifecycle.LifecycleCoroutineScope import com.ama.core.architecture.util.SpUtil import com.blankj.utilcode.util.StringUtils import com.remax.base.controller.SystemPageNavigationController import com.remax.base.ext.KvBoolDelegate import com.remax.base.ext.KvLongDelegate import com.remax.base.ext.canSendNotification import com.remax.base.ext.requestNotificationPermission import com.remax.base.report.DataReportManager import com.remax.base.utils.ActivityLauncher import com.vididin.real.money.game.R import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine import java.util.Calendar import kotlin.coroutines.resume object NotificationController { private var lowVersionNotificationGranted by KvBoolDelegate( "notification_lowVersionNotificationGr", false ) private var lastNotificationDialogTime by KvLongDelegate("notification_last_dialog_time", 0L) /** * 检查是否可以显示通知权限对话框(每天最多显示一次) * @return true 如果可以显示,false 如果不可以显示 */ private fun canShowNotificationDialog(): Boolean { val currentTime = System.currentTimeMillis() // 如果从未显示过,可以显示 if (lastNotificationDialogTime == 0L) { return true } // 检查是否在同一天内已经显示过 val lastShowDate = Calendar.getInstance().apply { timeInMillis = lastNotificationDialogTime } val currentDate = Calendar.getInstance().apply { timeInMillis = currentTime } // 检查是否是同一天 val isSameDay = lastShowDate.get(Calendar.YEAR) == currentDate.get(Calendar.YEAR) && lastShowDate.get(Calendar.DAY_OF_YEAR) == currentDate.get(Calendar.DAY_OF_YEAR) return !isSameDay } private fun trackNotificationCompat(context: Activity) { // 有权限时,如是低版本的,说明是自动授权,埋点上报一次 if (context.canSendNotification() && Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { if (!lowVersionNotificationGranted) { lowVersionNotificationGranted = true DataReportManager.reportData( "Notific_Allow_Start", mapOf("Notific_Allow_Position" to "Appstart") ) DataReportManager.reportData( "Notific_Allow_Result", mapOf( "Notific_Allow_Position" to "Appstart", "Result" to "allow1" ) ) } } } // 阻塞请求 suspend fun requestNotificationPermissionAsWait( context: Activity, activityLauncher: ActivityLauncher, onGrantedOnlyUnauthorized: (isGranted: Boolean) -> Unit ): Boolean { // 低版本埋点 trackNotificationCompat(context) // 高版本请求 if (!context.canSendNotification()) { DataReportManager.reportData( "Notific_Allow_Start", mapOf("Notific_Allow_Position" to "Appstart") ) return runCatching { suspendCancellableCoroutine { continuation -> context.requestNotificationPermission(activityLauncher!!) { isGranted -> DataReportManager.reportData( "Notific_Allow_Result", mapOf( "Notific_Allow_Position" to "Appstart", "Result" to if (isGranted) "allow" else if (ActivityCompat.shouldShowRequestPermissionRationale( context, Manifest.permission.POST_NOTIFICATIONS ) ) "denied" else "deined_forever" ) ) onGrantedOnlyUnauthorized.invoke(isGranted) if (continuation.isActive) { continuation.resume(isGranted) } } } }.getOrDefault(false) } return true } // 异步请求 fun requestNotificationPermissionAsAsync( context: Activity, lifecycleScope: LifecycleCoroutineScope, activityLauncher: ActivityLauncher, position: String, onGrantedOnlyUnauthorized: (isGranted: Boolean) -> Unit ) { lifecycleScope.launch { delay(300) if (!context.canSendNotification() /*&& canShowNotificationDialog()*/) { // 记录显示时间 lastNotificationDialogTime = System.currentTimeMillis() /*ConfirmationDialog.showNotification( context = context, title = StringUtils.getString(R.string.notification_dialog_title), message = StringUtils.getString(R.string.notification_dialog_message), onConfirm = { runCatching { realRequest(context, activityLauncher, position, onGrantedOnlyUnauthorized) } .onFailure { it.printStackTrace() } })*/ runCatching { realRequest(context, activityLauncher, position, onGrantedOnlyUnauthorized) } } } } private fun realRequest( context: Activity, activityLauncher: ActivityLauncher, position: String, onGrantedOnlyUnauthorized: (Boolean) -> Unit ) { DataReportManager.reportData( "Notific_Allow_Start", mapOf("Notific_Allow_Position" to position) ) if (isNotificationPermissionGranted(context)) { return } // android判断是否永久拒绝的api存在故意设计 // 权限弹框用户点了返回键也算是一次拒绝 if (!SpUtil.instance().getBoolean(SpUtil.KEY_HAS_REQUEST_NOTIFICATION_PERMISSION) || ActivityCompat.shouldShowRequestPermissionRationale( context, Manifest.permission.POST_NOTIFICATIONS ) ) { context.requestNotificationPermission(activityLauncher!!) { isGranted -> DataReportManager.reportData( "Notific_Allow_Result", mapOf( "Notific_Allow_Position" to "Appstart", "Result" to if (isGranted) "allow" else "denied" ) ) onGrantedOnlyUnauthorized.invoke(isGranted) } SpUtil.instance().putBoolean(SpUtil.KEY_HAS_REQUEST_NOTIFICATION_PERMISSION, true) } else { SystemPageNavigationController.markEnterNotificationAccessPage() activityLauncher.launch(Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply { putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName) }) { // 权限检查完成后,标记离开系统页面 SystemPageNavigationController.markLeaveSystemPage() // 检查通知权限状态并回调结果 val isGranted = context.canSendNotification() DataReportManager.reportData( "Notific_Allow_Result", mapOf( "Notific_Allow_Position" to "Appstart", "Result" to if (isGranted) "allow" else "denied_forever" ) ) onGrantedOnlyUnauthorized.invoke(isGranted) } } } private fun isNotificationPermissionGranted(context: Context): Boolean { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { ContextCompat.checkSelfPermission( context, Manifest.permission.POST_NOTIFICATIONS ) == PackageManager.PERMISSION_GRANTED } else { true } } }