diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/OnlineMsgServer.iml b/.idea/OnlineMsgServer.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/OnlineMsgServer.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml
new file mode 100644
index 0000000..23267a6
--- /dev/null
+++ b/.idea/caches/deviceStreaming.xml
@@ -0,0 +1,1490 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..4b151ab
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..7801fe1
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android-client/app/src/main/java/com/onlinemsg/client/MainActivity.kt b/android-client/app/src/main/java/com/onlinemsg/client/MainActivity.kt
index defba49..a07bba6 100644
--- a/android-client/app/src/main/java/com/onlinemsg/client/MainActivity.kt
+++ b/android-client/app/src/main/java/com/onlinemsg/client/MainActivity.kt
@@ -9,9 +9,11 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
+import com.onlinemsg.client.service.ChatForegroundService
import com.onlinemsg.client.ui.OnlineMsgApp
class MainActivity : ComponentActivity() {
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestNotificationPermissionIfNeeded()
@@ -21,21 +23,53 @@ class MainActivity : ComponentActivity() {
}
}
+ private val PERMISSION_REQUEST_NOTIFICATIONS = 1001
+
private fun requestNotificationPermissionIfNeeded() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return
val granted = ContextCompat.checkSelfPermission(
this,
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
- if (granted) return
- ActivityCompat.requestPermissions(
- this,
- arrayOf(Manifest.permission.POST_NOTIFICATIONS),
- REQUEST_NOTIFICATION_PERMISSION
- )
+ if (granted) {
+ // 已有权限
+ startForegroundServiceIfNeeded()
+ } else {
+ // 请求权限
+ ActivityCompat.requestPermissions(
+ this,
+ arrayOf(Manifest.permission.POST_NOTIFICATIONS),
+ REQUEST_NOTIFICATION_PERMISSION
+ )
+ }
+ }
+
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array,
+ grantResults: IntArray
+ ) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ when (requestCode) {
+ REQUEST_NOTIFICATION_PERMISSION -> {
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ /* 授予权限的处理 */
+ startForegroundServiceIfNeeded()
+ } else {
+ /* 拒绝权限的处理 */
+ }
+ }
+ }
+ }
+
+ /**
+ * 根据业务逻辑决定何时启动前台服务(@emilia-t)
+ */
+ private fun startForegroundServiceIfNeeded() {
+ ChatForegroundService.start(this)
}
private companion object {
const val REQUEST_NOTIFICATION_PERMISSION = 1002
}
-}
+}
\ No newline at end of file
diff --git a/android-client/app/src/main/java/com/onlinemsg/client/service/ChatForegroundService.kt b/android-client/app/src/main/java/com/onlinemsg/client/service/ChatForegroundService.kt
index 0ebaa12..8566d22 100644
--- a/android-client/app/src/main/java/com/onlinemsg/client/service/ChatForegroundService.kt
+++ b/android-client/app/src/main/java/com/onlinemsg/client/service/ChatForegroundService.kt
@@ -21,6 +21,10 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
+import android.Manifest
+import android.content.pm.PackageManager
+import android.util.Log
+import android.annotation.SuppressLint
class ChatForegroundService : Service() {
@@ -62,6 +66,18 @@ class ChatForegroundService : Service() {
override fun onBind(intent: Intent?): IBinder? = null
+ /**
+ * 权限检查函数(@emilia-t)
+ */
+ private fun hasNotificationPermission(): Boolean {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
+ } else {
+ true // 低于 Android 13 不需要权限
+ }
+ }
+
+ @SuppressLint("MissingPermission")
private fun observeStatusAndRefreshNotification() {
if (statusJob != null) return
statusJob = serviceScope.launch {
@@ -69,10 +85,15 @@ class ChatForegroundService : Service() {
.map { it.status to it.statusHint }
.distinctUntilChanged()
.collect { (status, hint) ->
- NotificationManagerCompat.from(this@ChatForegroundService).notify(
- FOREGROUND_NOTIFICATION_ID,
- buildForegroundNotification(status, hint)
- )
+ /* 检查是否有通知权限(@emilia-t) */
+ if (hasNotificationPermission()) {
+ NotificationManagerCompat.from(this@ChatForegroundService).notify(
+ FOREGROUND_NOTIFICATION_ID,
+ buildForegroundNotification(status, hint)
+ )
+ } else {
+ Log.d("ChatForegroundService", "通知权限缺失,跳过前台通知更新")
+ }
if (status == ConnectionStatus.IDLE && !ChatSessionManager.shouldForegroundServiceRun()) {
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()