VidiDin-Android/app/src/main/java/com/gamedog/vididin/manager/NotificationController.kt

209 lines
8.2 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<Boolean> { 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
}
}
}