From 4af871597f94631e18cc03a35bedea2679e14d9f Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Fri, 27 Feb 2026 16:44:06 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts |  236 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 200 insertions(+), 36 deletions(-)

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 bacf33a..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
@@ -4,6 +4,18 @@
 import Settings from 'android.provider.Settings'
 import { UTSAndroid } from 'io.dcloud.uts'
 import BatteryManager from 'android.os.BatteryManager'
+import NotificationChannel from 'android.app.NotificationChannel'
+import NotificationManager from 'android.app.NotificationManager'
+import Notification from 'android.app.Notification'
+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'
+const CALL_NOTIFICATION_ID: Int = 2001
 
 // 拉起应用
 export function openDialog(): void {
@@ -27,12 +39,14 @@
 	if (context == null) return
 	// 1. 检查悬浮窗权限 (Android 6.0+)
 	const noneFloat = Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)
-	if (noneFloat) {
-		uni.showToast({ title: '请允许应用悬浮在屏幕上', icon: 'none' })
-	} else {
-		setTimeout(() => {
+	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)
@@ -40,45 +54,71 @@
 			} catch (e) {
 				console.error(e)
 			}
-		}, 2000)
-	}
+		})
+		.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()
 }
 
 /**
@@ -100,3 +140,127 @@
 	return '0%'
 }
 
+/**
+ * 显示来电通知(锁屏/后台可弹出)
+ * 利用高优先级通知 + fullScreenIntent 实现锁屏/后台来电提醒
+ * @param callerName 来电者名称
+ */
+export function showIncomingCallNotification(callerName: string): void {
+	const context = UTSAndroid.getAppContext()
+	if (context == null) return
+
+	try {
+		// 1. 创建来电通知渠道(IMPORTANCE_HIGH → Heads-up 弹出)
+		if (Build.VERSION.SDK_INT >= 26) {
+			const channel = new NotificationChannel(
+				CALL_CHANNEL_ID,
+				'来电通知',
+				NotificationManager.IMPORTANCE_HIGH
+			)
+			channel.setDescription('语音来电通知')
+			channel.enableVibration(true)
+			channel.enableLights(true)
+			channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC)
+			channel.setBypassDnd(true)
+
+			const nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+			nm.createNotificationChannel(channel)
+		}
+
+		// 2. 构建点击通知后打开应用的 Intent
+		const pm = context.getPackageManager()
+		const launchIntent = pm.getLaunchIntentForPackage(context.getPackageName())
+		if (launchIntent != null) {
+			launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+			launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+		}
+
+		let pendingIntentFlags = PendingIntent.FLAG_UPDATE_CURRENT
+		if (Build.VERSION.SDK_INT >= 31) {
+			pendingIntentFlags = pendingIntentFlags | PendingIntent.FLAG_IMMUTABLE
+		}
+
+		const contentIntent = PendingIntent.getActivity(context, 0, launchIntent, pendingIntentFlags)
+		// fullScreenIntent 用于锁屏时全屏展示
+		const fullScreenIntent = PendingIntent.getActivity(context, 1, launchIntent, pendingIntentFlags)
+
+		// 3. 构建通知
+		const appInfo = context.getApplicationInfo()
+		const appIcon = appInfo.icon
+
+		let builder: Notification.Builder
+		if (Build.VERSION.SDK_INT >= 26) {
+			builder = new Notification.Builder(context, CALL_CHANNEL_ID)
+		} else {
+			builder = new Notification.Builder(context)
+		}
+
+		builder
+			.setSmallIcon(appIcon)
+			.setContentTitle('语音来电')
+			.setContentText(callerName + ' 正在呼叫您')
+			.setContentIntent(contentIntent)
+			.setFullScreenIntent(fullScreenIntent, true)  // 🔑 锁屏全屏弹出
+			.setOngoing(true)
+			.setAutoCancel(false)
+			.setPriority(Notification.PRIORITY_MAX)
+			.setVisibility(Notification.VISIBILITY_PUBLIC) // 锁屏显示完整内容
+
+		if (Build.VERSION.SDK_INT >= 21) {
+			builder.setCategory(Notification.CATEGORY_CALL) // 标记为来电类型
+		}
+
+
+
+		const notification = builder.build()
+		// 设置通知标志:保持常亮、不可清除
+		notification.flags = notification.flags | Notification.FLAG_INSISTENT | Notification.FLAG_NO_CLEAR
+
+		// 4. 发送通知
+		const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+		notificationManager.notify(CALL_NOTIFICATION_ID, notification)
+
+		// 5. 如果在锁屏状态,尝试亮屏
+		wakeUpScreen(context)
+
+		console.log('showIncomingCallNotification: 来电通知已发送,来电者:', callerName)
+	} catch (e) {
+		console.error('showIncomingCallNotification: 发送来电通知失败', e)
+	}
+}
+
+/**
+ * 取消来电通知
+ * 在接听或拒接后调用
+ */
+export function cancelIncomingCallNotification(): void {
+	const context = UTSAndroid.getAppContext()
+	if (context == null) return
+
+	try {
+		const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+		notificationManager.cancel(CALL_NOTIFICATION_ID)
+		console.log('cancelIncomingCallNotification: 来电通知已取消')
+	} catch (e) {
+		console.error('cancelIncomingCallNotification: 取消来电通知失败', e)
+	}
+}
+
+/**
+ * 唤醒屏幕(锁屏时亮屏)
+ */
+function wakeUpScreen(context: Context): void {
+	try {
+		const powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+		if (!powerManager.isInteractive()) {
+			// 屏幕关闭,唤醒屏幕
+			const screenLock = powerManager.newWakeLock(
+				PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
+				'IncomingCall::WakeUp'
+			)
+			screenLock.acquire(10000) // 保持亮屏 10 秒
+		}
+	} catch (e) {
+		console.error('wakeUpScreen: 唤醒屏幕失败', e)
+	}
+}

--
Gitblit v1.9.3