Compare commits
2 Commits
5f07605a06
...
9082f15b63
| Author | SHA1 | Date | |
|---|---|---|---|
| 9082f15b63 | |||
| 1ac177be8b |
@@ -16,18 +16,25 @@ class MainActivity : ComponentActivity() {
|
|||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
|
|
||||||
// 设置全屏显示
|
// 设置全屏显示
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, true)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
// 设置状态栏图标颜色
|
// 设置状态栏图标颜色
|
||||||
val windowInsetsController = WindowInsetsControllerCompat(window, window.decorView)
|
val controller = WindowInsetsControllerCompat(window, window.decorView)
|
||||||
// windowInsetsController.hide(WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.navigationBars())
|
// windowInsetsController.hide(WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.navigationBars())
|
||||||
// windowInsetsController.systemBarsBehavior =
|
// windowInsetsController.systemBarsBehavior =
|
||||||
// WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
// WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
|
|
||||||
|
// 显示状态栏和导航栏
|
||||||
|
// controller.show(WindowInsetsCompat.Type.systemBars())
|
||||||
|
|
||||||
|
// 设置系统栏行为:用户上滑时再显示(可选)
|
||||||
|
// controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_DEFAULT
|
||||||
|
|
||||||
// 使用系统原生方法检测暗色主题
|
// 使用系统原生方法检测暗色主题
|
||||||
val isDarkTheme = resources.configuration.uiMode and
|
val isDarkTheme = resources.configuration.uiMode and
|
||||||
Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||||
windowInsetsController.isAppearanceLightStatusBars = !isDarkTheme
|
controller.isAppearanceLightStatusBars = isDarkTheme
|
||||||
|
controller.isAppearanceLightNavigationBars = isDarkTheme
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
App()
|
App()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.taskttl.core.alarm
|
|||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import com.taskttl.core.notification.NotificationManager
|
import com.taskttl.core.notification.AppNotificationManager
|
||||||
import com.taskttl.core.notification.NotificationPayload
|
import com.taskttl.core.notification.NotificationPayload
|
||||||
import com.taskttl.core.notification.NotificationRepeatType
|
import com.taskttl.core.notification.NotificationRepeatType
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -20,7 +20,7 @@ class AlarmReceiver : BroadcastReceiver() {
|
|||||||
|
|
||||||
// 使用协程调用统一通知方法
|
// 使用协程调用统一通知方法
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
NotificationManager.scheduleNotification(
|
AppNotificationManager.scheduleNotification(
|
||||||
NotificationPayload(
|
NotificationPayload(
|
||||||
id = id,
|
id = id,
|
||||||
title = title,
|
title = title,
|
||||||
@@ -30,38 +30,5 @@ class AlarmReceiver : BroadcastReceiver() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// val id = intent.getStringExtra("id") ?: return
|
|
||||||
// val title = intent.getStringExtra("title") ?: "TaskTTL"
|
|
||||||
// val message = intent.getStringExtra("message") ?: ""
|
|
||||||
//
|
|
||||||
// val channelId = "taskttl_channel"
|
|
||||||
//
|
|
||||||
// // 确保通道存在
|
|
||||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
// val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
|
|
||||||
// if (nm.getNotificationChannel(channelId) == null) {
|
|
||||||
// val channel = android.app.NotificationChannel(
|
|
||||||
// channelId,
|
|
||||||
// "TaskTTL Notifications",
|
|
||||||
// android.app.NotificationManager.IMPORTANCE_HIGH
|
|
||||||
// )
|
|
||||||
// channel.description = "TaskTTL 提醒通知"
|
|
||||||
// nm.createNotificationChannel(channel)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 构建通知
|
|
||||||
// val builder = NotificationCompat.Builder(context, channelId)
|
|
||||||
// .setContentTitle(title)
|
|
||||||
// .setContentText(message)
|
|
||||||
// .setSmallIcon(R.mipmap.ic_launcher)
|
|
||||||
// .setAutoCancel(true)
|
|
||||||
// .setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
||||||
//
|
|
||||||
// val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
|
|
||||||
// nm.notify(id.hashCode(), builder.build())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.taskttl.core.notification
|
|||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -12,7 +13,11 @@ import android.os.Build
|
|||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.work.*
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import androidx.work.workDataOf
|
||||||
import com.taskttl.MainApplication
|
import com.taskttl.MainApplication
|
||||||
import com.taskttl.R
|
import com.taskttl.R
|
||||||
import com.taskttl.core.alarm.AlarmReceiver
|
import com.taskttl.core.alarm.AlarmReceiver
|
||||||
@@ -20,7 +25,7 @@ import com.taskttl.core.utils.LogUtils
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
actual object NotificationManager {
|
actual object AppNotificationManager {
|
||||||
|
|
||||||
private val channelId = "taskttl_channel"
|
private val channelId = "taskttl_channel"
|
||||||
|
|
||||||
@@ -35,13 +40,14 @@ actual object NotificationManager {
|
|||||||
private fun setupNotificationChannel() {
|
private fun setupNotificationChannel() {
|
||||||
val activity = MainApplication.currentActivity() ?: return
|
val activity = MainApplication.currentActivity() ?: return
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val nm = activity.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
|
val nm =
|
||||||
|
activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
if (nm.getNotificationChannel(channelId) == null) {
|
if (nm.getNotificationChannel(channelId) == null) {
|
||||||
val channel = android.app.NotificationChannel(
|
val channel = android.app.NotificationChannel(
|
||||||
channelId,
|
channelId,
|
||||||
"TaskTTL Notifications",
|
"TaskTTL Notifications",
|
||||||
android.app.NotificationManager.IMPORTANCE_HIGH
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
).apply { description = "TaskTTL 提醒通知" }
|
)
|
||||||
nm.createNotificationChannel(channel)
|
nm.createNotificationChannel(channel)
|
||||||
LogUtils.d("DevTTL_NotificationTest", "Notification channel created")
|
LogUtils.d("DevTTL_NotificationTest", "Notification channel created")
|
||||||
}
|
}
|
||||||
@@ -137,10 +143,11 @@ actual object NotificationManager {
|
|||||||
else -> 24 * 60 * 60 * 1000L
|
else -> 24 * 60 * 60 * 1000L
|
||||||
}
|
}
|
||||||
|
|
||||||
val request = PeriodicWorkRequestBuilder<NotificationWorker>(interval, TimeUnit.MILLISECONDS)
|
val request =
|
||||||
.setInputData(data)
|
PeriodicWorkRequestBuilder<NotificationWorker>(interval, TimeUnit.MILLISECONDS)
|
||||||
.addTag(payload.id)
|
.setInputData(data)
|
||||||
.build()
|
.addTag(payload.id)
|
||||||
|
.build()
|
||||||
|
|
||||||
workManager.enqueueUniquePeriodicWork(
|
workManager.enqueueUniquePeriodicWork(
|
||||||
payload.id,
|
payload.id,
|
||||||
@@ -153,7 +160,8 @@ actual object NotificationManager {
|
|||||||
/** 立即显示通知 */
|
/** 立即显示通知 */
|
||||||
private fun showImmediateNotification(payload: NotificationPayload) {
|
private fun showImmediateNotification(payload: NotificationPayload) {
|
||||||
val activity = getActivity()
|
val activity = getActivity()
|
||||||
val nm = activity.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
|
val nm =
|
||||||
|
activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
|
||||||
val notification = NotificationCompat.Builder(activity, channelId)
|
val notification = NotificationCompat.Builder(activity, channelId)
|
||||||
.setContentTitle(payload.title)
|
.setContentTitle(payload.title)
|
||||||
@@ -184,14 +192,16 @@ actual object NotificationManager {
|
|||||||
)
|
)
|
||||||
alarmManager.cancel(pendingIntent)
|
alarmManager.cancel(pendingIntent)
|
||||||
|
|
||||||
val nm = activity.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
|
val nm =
|
||||||
|
activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
nm.cancel(id.hashCode())
|
nm.cancel(id.hashCode())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual suspend fun cancelAll() {
|
actual suspend fun cancelAll() {
|
||||||
val activity = getActivity()
|
val activity = getActivity()
|
||||||
WorkManager.getInstance(activity).cancelAllWork()
|
WorkManager.getInstance(activity).cancelAllWork()
|
||||||
val nm = activity.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
|
val nm =
|
||||||
|
activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
nm.cancelAll()
|
nm.cancelAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.taskttl.core.notification
|
package com.taskttl.core.notification
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -48,7 +49,7 @@ class NotificationWorker(
|
|||||||
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
|
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
|
||||||
val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
|
val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
nm.notify(id.hashCode(), builder.build())
|
nm.notify(id.hashCode(), builder.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ package com.taskttl.core.notification
|
|||||||
* 通知管理器
|
* 通知管理器
|
||||||
* @author admin
|
* @author admin
|
||||||
* @date 2025/10/16
|
* @date 2025/10/16
|
||||||
* @constructor 创建[NotificationManager]
|
* @constructor 创建[AppNotificationManager]
|
||||||
*/
|
*/
|
||||||
expect object NotificationManager {
|
expect object AppNotificationManager {
|
||||||
/**
|
/**
|
||||||
* 日程通知
|
* 日程通知
|
||||||
* @param [payload] 有效载荷
|
* @param [payload] 有效载荷
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.taskttl.core.routes
|
package com.taskttl.core.routes
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.List
|
import androidx.compose.material.icons.automirrored.filled.List
|
||||||
@@ -14,6 +16,7 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavDestination.Companion.hasRoute
|
import androidx.navigation.NavDestination.Companion.hasRoute
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
@@ -22,12 +25,12 @@ import androidx.navigation.compose.rememberNavController
|
|||||||
import androidx.navigation.toRoute
|
import androidx.navigation.toRoute
|
||||||
import com.taskttl.core.routes.Routes.Main
|
import com.taskttl.core.routes.Routes.Main
|
||||||
import com.taskttl.core.ui.CustomBottomBar
|
import com.taskttl.core.ui.CustomBottomBar
|
||||||
|
import com.taskttl.presentation.category.CategoryEditScreen
|
||||||
|
import com.taskttl.presentation.category.CategoryScreen
|
||||||
import com.taskttl.presentation.countdown.CountdownDetailScreen
|
import com.taskttl.presentation.countdown.CountdownDetailScreen
|
||||||
import com.taskttl.presentation.countdown.CountdownEditScreen
|
import com.taskttl.presentation.countdown.CountdownEditScreen
|
||||||
import com.taskttl.presentation.countdown.CountdownScreen
|
import com.taskttl.presentation.countdown.CountdownScreen
|
||||||
import com.taskttl.presentation.settings.AboutScreen
|
import com.taskttl.presentation.settings.AboutScreen
|
||||||
import com.taskttl.presentation.category.CategoryEditScreen
|
|
||||||
import com.taskttl.presentation.category.CategoryScreen
|
|
||||||
import com.taskttl.presentation.settings.DataManagementScreen
|
import com.taskttl.presentation.settings.DataManagementScreen
|
||||||
import com.taskttl.presentation.settings.FeedbackScreen
|
import com.taskttl.presentation.settings.FeedbackScreen
|
||||||
import com.taskttl.presentation.settings.PrivacyScreen
|
import com.taskttl.presentation.settings.PrivacyScreen
|
||||||
@@ -61,7 +64,8 @@ fun MainNav() {
|
|||||||
val currentDestination by mainNavController.currentBackStackEntryAsState()
|
val currentDestination by mainNavController.currentBackStackEntryAsState()
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.background(Color(0xffF9F9F9)),
|
modifier = Modifier.fillMaxSize().background(Color(0xffF9F9F9)),
|
||||||
|
contentWindowInsets = WindowInsets(0.dp),
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
CustomBottomBar(
|
CustomBottomBar(
|
||||||
bottomItems = bottomItems,
|
bottomItems = bottomItems,
|
||||||
@@ -80,7 +84,8 @@ fun MainNav() {
|
|||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
NavHost(
|
NavHost(
|
||||||
modifier = Modifier.fillMaxSize().padding(paddingValues),
|
modifier = Modifier.fillMaxSize()
|
||||||
|
.padding(bottom = paddingValues.calculateBottomPadding()),
|
||||||
navController = mainNavController,
|
navController = mainNavController,
|
||||||
startDestination = Main.Task
|
startDestination = Main.Task
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Column
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@@ -42,7 +43,7 @@ fun CustomBottomBar(
|
|||||||
val barHeight = 56.dp
|
val barHeight = 56.dp
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxWidth().height(barHeight)
|
modifier = Modifier.navigationBarsPadding().fillMaxWidth().height(barHeight)
|
||||||
.background(MaterialTheme.colorScheme.background)
|
.background(MaterialTheme.colorScheme.background)
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.taskttl.data.di
|
package com.taskttl.data.di
|
||||||
|
|
||||||
import com.taskttl.core.notification.NotificationManager
|
|
||||||
import com.taskttl.data.repository.OnboardingRepository
|
import com.taskttl.data.repository.OnboardingRepository
|
||||||
import com.taskttl.data.repository.SettingsRepository
|
import com.taskttl.data.repository.SettingsRepository
|
||||||
import com.taskttl.data.repository.impl.OnboardingRepositoryImpl
|
import com.taskttl.data.repository.impl.OnboardingRepositoryImpl
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Arrangement
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@@ -53,6 +54,7 @@ fun AppHeader(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.background(brush = gradient)
|
.background(brush = gradient)
|
||||||
|
.statusBarsPadding()
|
||||||
.padding(horizontal = 20.dp, vertical = 15.dp),
|
.padding(horizontal = 20.dp, vertical = 15.dp),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.taskttl.core.notification
|
|||||||
|
|
||||||
import platform.UserNotifications.*
|
import platform.UserNotifications.*
|
||||||
|
|
||||||
actual class NotificationManager {
|
actual object AppNotificationManager {
|
||||||
actual suspend fun scheduleNotification(payload: NotificationPayload) {
|
actual suspend fun scheduleNotification(payload: NotificationPayload) {
|
||||||
val content = UNMutableNotificationContent().apply {
|
val content = UNMutableNotificationContent().apply {
|
||||||
title = payload.title
|
title = payload.title
|
||||||
Reference in New Issue
Block a user