import Build from 'android.os.Build'
|
import Context from 'android.content.Context'
|
import Intent from 'android.content.Intent'
|
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 {
|
const context = UTSAndroid.getAppContext()
|
if (context == null) return
|
try {
|
const pm = context.getPackageManager()
|
const intent = pm.getLaunchIntentForPackage(context.getPackageName())
|
if (intent != null) {
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
context.startActivity(intent)
|
}
|
} catch (e) {
|
console.error(e)
|
}
|
}
|
|
// 跳到允许悬浮窗权限页面
|
export function allowFloat() {
|
const context = UTSAndroid.getAppContext()
|
if (context == null) return
|
// 1. 检查悬浮窗权限 (Android 6.0+)
|
const noneFloat = Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)
|
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
|
// 后台弹出界面无标准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
|
// 锁屏显示依赖通知权限,检查通知是否开启
|
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()
|
}
|
|
/**
|
* 获取电池电量百分比
|
*
|
* uni-app项目中调用示例:
|
* import { getBatteryCapacity } from "@/uni_modules/lgh-getbatteryinfo"
|
* const capacity = getBatteryCapacity()
|
* console.log('电池电量:', capacity)
|
*/
|
export function getBatteryCapacity(): string {
|
// 获取android系统 application上下文
|
const context = UTSAndroid.getAppContext()
|
if (context != null) {
|
const manager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
|
const currentLevel: number = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
|
return '' + currentLevel + '%'
|
}
|
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)
|
}
|
}
|