From e00da17ae2adaecf1cdf2d5128e357a50607bc90 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Fri, 27 Feb 2026 08:40:37 +0800
Subject: [PATCH] feat: 权限获取调整

---
 uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts |  124 ++++++++++++++----------
 uniapps/work-app/src/uni_modules/keep-app/utssdk/app-android/index.uts   |   65 +++++++-----
 uniapps/work-app/src/hooks/useGlobalWS.js                                |   15 ++
 uniapps/work-app/src/App.vue                                             |   51 +---------
 4 files changed, 126 insertions(+), 129 deletions(-)

diff --git a/uniapps/work-app/src/App.vue b/uniapps/work-app/src/App.vue
index abcd560..241db70 100644
--- a/uniapps/work-app/src/App.vue
+++ b/uniapps/work-app/src/App.vue
@@ -51,54 +51,13 @@
 	keepAliveStart()
 
 	//显示悬浮窗权限
-	// setTimeout(allowFloat, 5000)
-
+	setTimeout(allowFloat, 5000)
 	// 请求用户允许忽略电池优化(重要:用于保活)
-	setTimeout(() => {
-		if (!isIgnoringBatteryOptimizations()) {
-			uni.showModal({
-				title: '权限提示',
-				content: '为了在后台收到来电时能弹出通话界面,请将应用添加到电池优化白名单',
-				confirmText: '去设置',
-				cancelText: '暂不',
-				success(res) {
-					if (res.confirm) {
-						requestIgnoreBatteryOptimization()
-					}
-				}
-			})
-		}
-	}, 10000)
-
+	setTimeout(requestIgnoreBatteryOptimization, 10000)
 	// 引导用户开启「后台弹出界面」权限
-	// setTimeout(() => {
-	// 	uni.showModal({
-	// 		title: '权限提示',
-	// 		content: '为了在后台收到来电时能弹出通话界面,请开启“后台弹出界面”权限',
-	// 		confirmText: '去设置',
-	// 		cancelText: '暂不',
-	// 		success(res) {
-	// 			if (res.confirm) {
-	// 				allowBackgroundPopup()
-	// 			}
-	// 		}
-	// 	})
-	// }, 15000)
-	//
-	// // 引导用户开启「锁屏显示」权限
-	// setTimeout(() => {
-	// 	uni.showModal({
-	// 		title: '权限提示',
-	// 		content: '为了在锁屏时能显示来电通知,请开启“锁屏显示通知”权限',
-	// 		confirmText: '去设置',
-	// 		cancelText: '暂不',
-	// 		success(res) {
-	// 			if (res.confirm) {
-	// 				allowLockScreen()
-	// 			}
-	// 		}
-	// 	})
-	// }, 20000)
+	setTimeout(allowBackgroundPopup, 15000)
+	//  引导用户开启「锁屏显示」权限
+	setTimeout(allowLockScreen, 20000)
 
 	// #endif
 }
diff --git a/uniapps/work-app/src/hooks/useGlobalWS.js b/uniapps/work-app/src/hooks/useGlobalWS.js
index 36086d1..0026451 100644
--- a/uniapps/work-app/src/hooks/useGlobalWS.js
+++ b/uniapps/work-app/src/hooks/useGlobalWS.js
@@ -2,7 +2,7 @@
 import useAppStore from "../store/modules/app/index.js";
 import websocketService from "@/utils/websocket.js";
 // #ifdef APP-PLUS
-import { openDialog, allowFloat, getBatteryCapacity } from '@/uni_modules/lgh-dialog'
+import { openDialog, allowFloat, getBatteryCapacity, showIncomingCallNotification, cancelIncomingCallNotification } from '@/uni_modules/lgh-dialog'
 // #endif
 export function useGlobalWS() {
 	const userStore = useUserStore();
@@ -27,8 +27,6 @@
     // 处理语音通话请求
     if (t === 'call') {
       console.log('📞 全局收到来电 call,来自', payload.from)
-      // 播放铃声
-      // playRingtone();
       // 触发震动
       triggerVibration();
       // 构建来电参数
@@ -37,7 +35,10 @@
         from: payload.from,
         type: 'incoming'
       };
-// #ifdef APP-PLUS
+      // #ifdef APP-PLUS
+      // 发送来电通知(锁屏/后台都会弹出 + 亮屏)
+      showIncomingCallNotification(payload.from || '未知来电')
+      // 拉起应用到前台
 			openDialog()
       // #endif
       // 转义参数以便在URL中传递
@@ -57,6 +58,12 @@
       }
       return
     }
+    // 通话接听或结束时,取消来电通知
+    if (t === 'accept' || t === 'reject' || t === 'hangup' || t === 'cancel') {
+      // #ifdef APP-PLUS
+      cancelIncomingCallNotification()
+      // #endif
+    }
   }
 
   // 播放来电铃声 - 定义在 messageHandler 外部
diff --git a/uniapps/work-app/src/uni_modules/keep-app/utssdk/app-android/index.uts b/uniapps/work-app/src/uni_modules/keep-app/utssdk/app-android/index.uts
index 2ce95f2..ec5a53b 100644
--- a/uniapps/work-app/src/uni_modules/keep-app/utssdk/app-android/index.uts
+++ b/uniapps/work-app/src/uni_modules/keep-app/utssdk/app-android/index.uts
@@ -11,6 +11,8 @@
 import PowerManager from 'android.os.PowerManager'
 import BatteryManager from 'android.os.BatteryManager'
 import { UTSAndroid } from 'io.dcloud.uts'
+import AlertDialog from 'android.app.AlertDialog'
+import DialogInterface from 'android.content.DialogInterface'
 
 // 保活服务的通知渠道ID
 const CHANNEL_ID = 'keep_alive_channel'
@@ -102,36 +104,7 @@
   return '0%'
 }
 
-/**
- * 请求忽略电池优化(需要用户手动确认)
- * 调用此方法会弹出系统设置页面
- */
-export function requestIgnoreBatteryOptimization(): void {
-  const context = UTSAndroid.getAppContext()
-  if (context == null) {
-    return
-  }
 
-  if (Build.VERSION.SDK_INT >= 23) {
-    // Android 6.0+
-    const powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
-    const packageName = context.getPackageName()
-
-    if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
-      try {
-        const intent = new Intent()
-        intent.setAction('android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS')
-        intent.setData(android.net.Uri.parse('package:' + packageName))
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-        context.startActivity(intent)
-      } catch (e) {
-        console.error('requestIgnoreBatteryOptimization: 打开设置失败', e)
-      }
-    } else {
-      console.log('requestIgnoreBatteryOptimization: 已在白名单中')
-    }
-  }
-}
 
 /**
  * 检查是否已忽略电池优化
@@ -152,6 +125,40 @@
 }
 
 /**
+ * 请求忽略电池优化(需要用户手动确认)
+ * 调用此方法会弹出系统设置页面
+ */
+export function requestIgnoreBatteryOptimization(): void {
+  if (isIgnoringBatteryOptimizations()) return
+  const activity = UTSAndroid.getUniActivity()
+  if (activity == null) return
+  AlertDialog.Builder(activity)
+    .setTitle('权限提示')
+    .setMessage('为了在后台收到来电时能弹出通话界面,请将应用添加到电池优化白名单')
+    .setPositiveButton('去设置', (_dialog : DialogInterface, _which : Int) => {
+      const context = UTSAndroid.getAppContext()
+      if (context == null) return
+      if (Build.VERSION.SDK_INT >= 23) {
+        const powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+        const packageName = context.getPackageName()
+        if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
+          try {
+            const intent = new Intent()
+            intent.setAction('android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS')
+            intent.setData(android.net.Uri.parse('package:' + packageName))
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+            context.startActivity(intent)
+          } catch (e) {
+            console.error('requestIgnoreBatteryOptimization: 打开设置失败', e)
+          }
+        }
+      }
+    })
+    .setNegativeButton('暂不', null)
+    .show()
+}
+
+/**
  * 创建通知渠道 (Android 8.0+ 必需)
  */
 function createNotificationChannel(context: Context): void {
diff --git a/uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts b/uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts
index 433c933..bf414ce 100644
--- a/uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts
+++ b/uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts
@@ -10,6 +10,8 @@
 import PendingIntent from 'android.app.PendingIntent'
 import PowerManager from 'android.os.PowerManager'
 import KeyguardManager from 'android.app.KeyguardManager'
+import AlertDialog from 'android.app.AlertDialog'
+import DialogInterface from 'android.content.DialogInterface'
 
 // 来电通知相关常量
 const CALL_CHANNEL_ID = 'incoming_call_channel'
@@ -37,64 +39,86 @@
 	if (context == null) return
 	// 1. 检查悬浮窗权限 (Android 6.0+)
 	const noneFloat = Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)
-	if (noneFloat) {
-    	uni.showModal({
-    		title: '权限提示',
-    		content: '为了在后台收到来电时能弹出通话界面,请开启“悬浮”权限',
-    		confirmText: '去设置',
-    		cancelText: '暂不',
-    		success(res) {
-    			if (res.confirm) {
-            try {
-              // 无权限,跳转到权限设置页面
-              const intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
-              intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
-              intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-              context.startActivity(intent)
-            } catch (e) {
-              console.error(e)
-            }
-    			}
-    		}
-    	})
-	}
+	if (!noneFloat) return
+	const activity = UTSAndroid.getUniActivity()
+	if (activity == null) return
+	AlertDialog.Builder(activity)
+		.setTitle('权限提示')
+		.setMessage('为了在后台收到来电时能弹出通话界面,请开启"悬浮窗"权限')
+		.setPositiveButton('去设置', (_dialog : DialogInterface, _which : Int) => {
+			try {
+				const intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
+				intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
+				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+				context.startActivity(intent)
+			} catch (e) {
+				console.error(e)
+			}
+		})
+		.setNegativeButton('暂不', null)
+		.show()
 }
 
 // 跳到后台弹出界面权限页面(应用详情设置)
 export function allowBackgroundPopup() {
-	const context = UTSAndroid.getAppContext()
-	if (context == null) return
-	try {
-		const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
-		intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
-		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-		context.startActivity(intent)
-	} catch (e) {
-		console.error(e)
-	}
+  const context = UTSAndroid.getAppContext()
+  if (context == null) return
+  // 后台弹出界面无标准API,用悬浮窗权限作为代理判断(有悬浮窗权限通常也允许后台弹出)
+  const nonePermission = Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)
+  if (!nonePermission) return
+  const activity = UTSAndroid.getUniActivity()
+  if (activity == null) return
+  AlertDialog.Builder(activity)
+    .setTitle('权限提示')
+    .setMessage('为了在后台收到来电时能弹出通话界面,请开启"后台弹出界面"权限')
+    .setPositiveButton('去设置', (_dialog : DialogInterface, _which : Int) => {
+      try {
+        const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+        intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        context.startActivity(intent)
+      } catch (e) {
+        console.error(e)
+      }
+    })
+    .setNegativeButton('暂不', null)
+    .show()
 }
 
 // 跳到锁屏显示权限页面(通知设置)
 export function allowLockScreen() {
-	const context = UTSAndroid.getAppContext()
-	if (context == null) return
-	try {
-		if (Build.VERSION.SDK_INT >= 26) {
-			// Android 8.0+ 跳转到应用通知设置
-			const intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
-			intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName())
-			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-			context.startActivity(intent)
-		} else {
-			// 低版本跳转到应用详情
-			const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
-			intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
-			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-			context.startActivity(intent)
-		}
-	} catch (e) {
-		console.error(e)
-	}
+  const context = UTSAndroid.getAppContext()
+  if (context == null) return
+  // 锁屏显示依赖通知权限,检查通知是否开启
+  const nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+  const nonePermission = !nm.areNotificationsEnabled()
+  if (!nonePermission) return
+  const activity = UTSAndroid.getUniActivity()
+  if (activity == null) return
+  AlertDialog.Builder(activity)
+    .setTitle('权限提示')
+    .setMessage('为了在锁屏时能显示来电通知,请开启"锁屏显示通知"权限')
+    .setPositiveButton('去设置', (_dialog : DialogInterface, _which : Int) => {
+      try {
+        if (Build.VERSION.SDK_INT >= 26) {
+          // Android 8.0+ 跳转到应用通知设置
+          const intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
+          intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName())
+          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+          context.startActivity(intent)
+        } else {
+          // 低版本跳转到应用详情
+          const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+          intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
+          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+          context.startActivity(intent)
+        }
+      } catch (e) {
+        console.error(e)
+      }
+    })
+    .setNegativeButton('暂不', null)
+    .show()
 }
 
 /**

--
Gitblit v1.9.3