209 lines
8.2 KiB
Kotlin
209 lines
8.2 KiB
Kotlin
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
|
||
}
|
||
}
|
||
|
||
} |