You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于为后台App添加本地通知振动及终止时通知处理的技术问询

Hey,这两个问题确实是本地通知开发里容易踩的坑,我给你分平台整理了具体的实现方案,亲测有效:

一、后台状态下为本地通知添加振动功能

iOS 实现

iOS后台状态下,本地通知要触发振动,关键是在创建通知请求时配置好振动相关参数,同时确保应用已经获取了通知权限(含振动权限)。

  1. 先完成权限申请:
import UserNotifications

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge, .criticalAlert]) { granted, error in
    if granted {
        print("通知权限已获取")
    }
}

其中.criticalAlert是iOS 12+的特性,能确保手机静音时也会振动;普通场景用.sound配合默认振动即可。

  1. 创建带振动的本地通知请求:
let content = UNMutableNotificationContent()
content.title = "后台通知测试"
content.body = "这是一条带振动的后台通知"
// 使用系统默认振动(搭配默认音效)
content.sound = UNNotificationSound.default
// 如需自定义振动模式(iOS 13+),可替换成以下代码:
// let vibrationPattern = [0, 500, 200, 500] // 暂停、振动、暂停、振动(单位:毫秒)
// content.vibrationPattern = vibrationPattern

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false)
let request = UNNotificationRequest(identifier: "vibrationNotification", content: content, trigger: trigger)

UNUserNotificationCenter.current().add(request) { error in
    if let error = error {
        print("添加通知失败:\(error.localizedDescription)")
    }
}

后台状态下只要通知正常触发,配置了振动参数就会自动生效,无需额外后台任务。

Android 实现

Android的振动需要结合通知通道(Android O及以上)和通知构建器配置,同时要提前申请振动权限。

  1. 在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.VIBRATE" />
  1. 创建带振动配置的通知通道:
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build

fun createNotificationChannel(context: Context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channelId = "vibration_channel"
        val channelName = "振动通知通道"
        val channelDescription = "用于发送带振动的本地通知"
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        
        val channel = NotificationChannel(channelId, channelName, importance).apply {
            description = channelDescription
            // 设置振动模式:延迟0ms,振动500ms,暂停200ms,振动500ms
            vibrationPattern = longArrayOf(0, 500, 200, 500)
            enableVibration(true)
        }
        
        val notificationManager = context.getSystemService(NotificationManager::class.java)
        notificationManager.createNotificationChannel(channel)
    }
}
  1. 发送带振动的本地通知:
import android.app.NotificationManager
import android.content.Context
import androidx.core.app.NotificationCompat

fun sendVibrationNotification(context: Context) {
    val channelId = "vibration_channel"
    val notificationBuilder = NotificationCompat.Builder(context, channelId)
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle("后台通知测试")
        .setContentText("这是一条带振动的后台通知")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // 兼容Android O以下版本的振动设置
        .setVibrate(longArrayOf(0, 500, 200, 500))
    
    val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.notify(1, notificationBuilder.build())
}

后台状态下,通知触发时会自动按照配置的振动模式执行。


二、解决应用终止时无法处理本地通知的问题

iOS 实现

应用被终止后,用户点击本地通知启动应用,需要在AppDelegate(或iOS 13+的SceneDelegate)中通过启动参数获取通知信息,同时要设置UNUserNotificationCenter的代理。

  1. 在AppDelegate中配置并处理:
import UIKit
import UserNotifications

@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 设置通知中心代理
        UNUserNotificationCenter.current().delegate = self
        
        // 检查是否从本地通知启动应用
        if let oldNotification = launchOptions?[.localNotification] as? UILocalNotification {
            handleLocalNotification(oldNotification)
        }
        // 处理iOS 10+的通知响应
        if let notificationResponse = launchOptions?[.notificationResponse] as? UNNotificationResponse {
            handleNotificationResponse(notificationResponse)
        }
        return true
    }
    
    // 处理iOS 9及以下的旧版本地通知
    private func handleLocalNotification(_ notification: UILocalNotification) {
        print("从终止状态启动,处理本地通知:\(notification.userInfo ?? [:])")
        // 这里写你的业务逻辑,比如跳转对应页面
    }
    
    // 处理iOS 10+的通知响应
    private func handleNotificationResponse(_ response: UNNotificationResponse) {
        let userInfo = response.notification.request.content.userInfo
        print("从终止状态启动,处理本地通知:\(userInfo)")
        // 业务逻辑处理
    }
    
    // 应用前台时的通知展示配置(可选)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound, .badge])
    }
    
    // 应用后台时点击通知的处理
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        handleNotificationResponse(response)
        completionHandler()
    }
}

如果是iOS 13+的SceneDelegate项目,需要在scene(_:willConnectTo:options:)方法中处理connectionOptions.notificationResponse。

Android 实现

应用被终止后,用户点击本地通知会启动指定Activity,需要在Activity的onCreate或onNewIntent方法中获取通知传递的数据。

  1. 发送通知时配置跳转和携带数据:
fun sendNotificationWithData(context: Context) {
    val channelId = "vibration_channel"
    // 创建跳转的Intent,携带通知数据
    val intent = Intent(context, MainActivity::class.java).apply {
        putExtra("notification_type", "local")
        putExtra("notification_data", "这是从终止状态点击通知带来的数据")
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    
    val pendingIntent = PendingIntent.getActivity(
        context,
        0,
        intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )
    
    val notificationBuilder = NotificationCompat.Builder(context, channelId)
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle("终止状态测试通知")
        .setContentText("点击启动应用并处理数据")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)
    
    val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.notify(2, notificationBuilder.build())
}
  1. 在Activity中处理通知数据:
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 处理从通知启动带来的数据
        intent?.let { handleNotificationData(it) }
    }
    
    // 处理应用后台时点击通知的情况(Activity已存在时)
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let { handleNotificationData(it) }
    }
    
    private fun handleNotificationData(intent: Intent) {
        val notificationType = intent.getStringExtra("notification_type")
        val notificationData = intent.getStringExtra("notification_data")
        
        if (notificationType == "local") {
            println("从终止状态启动,处理本地通知数据:$notificationData")
            // 你的业务逻辑,比如跳转对应页面、展示弹窗等
        }
    }
}

这样不管应用处于终止还是后台状态,点击通知都能正确获取并处理数据。


内容的提问来源于stack exchange,提问作者Geet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:00:36