| uniapps/work-app/src/App.vue | ●●●●● patch | view | raw | blame | history | |
| uniapps/work-app/src/hooks/useGlobalWS.js | ●●●●● patch | view | raw | blame | history | |
| uniapps/work-app/src/uni_modules/keep-app/utssdk/app-android/index.uts | ●●●●● patch | view | raw | blame | history | |
| uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts | ●●●●● patch | view | raw | blame | history |
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 } 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(); // 构建来电参数 @@ -38,6 +36,9 @@ type: 'incoming' }; // #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 外部 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 { 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,16 +39,14 @@ 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) { 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) @@ -54,16 +54,24 @@ } catch (e) { console.error(e) } } } }) } .setNegativeButton('暂不', null) .show() } // 跳到后台弹出界面权限页面(应用详情设置) export function allowBackgroundPopup() { 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())) @@ -72,12 +80,25 @@ } catch (e) { console.error(e) } }) .setNegativeButton('暂不', null) .show() } // 跳到锁屏显示权限页面(通知设置) export function allowLockScreen() { 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+ 跳转到应用通知设置 @@ -95,6 +116,9 @@ } catch (e) { console.error(e) } }) .setNegativeButton('暂不', null) .show() } /**