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

Flutter:触发特定通知后设备持续震动/响铃直至用户在APP内停止的方案咨询

实现持续震动/响铃通知及Flutter包推荐

核心实现思路

要实现特定通知触发后持续震动/响铃直至用户手动停止,需覆盖前台、后台、终止三种应用状态,核心步骤如下:

  • 推送通知携带自定义标识(如persistent_alert),区分普通通知和需要持续提醒的通知
  • 针对不同应用状态处理通知接收逻辑,启动持续震动/响铃服务
  • 在应用内提供手动停止入口,触发终止提醒的操作

推荐Flutter包

以下是支持全状态(含终止状态)的实用包:

  • flutter_local_notifications:核心通知处理包,支持自定义震动模式,可配合推送服务在终止状态下唤醒应用
  • vibration:专注震动控制,支持循环震动,适配Android/iOS
  • audio_service:用于后台持续播放铃声,支持全状态音频播放,需配合just_audio使用
  • firebase_messaging:处理FCM推送,实现跨状态的通知接收与回调

具体实现示例

1. 持续震动实现

依赖配置

dependencies:
  flutter_local_notifications: ^16.1.0
  vibration: ^1.7.6
  firebase_messaging: ^14.6.1

代码逻辑

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:vibration/vibration.dart';

// 后台消息处理(终止/后台状态触发)
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  if (message.data['alert_type'] == 'persistent') {
    // 启动循环震动:500ms震动 + 500ms间隔,repeat:0表示无限循环
    Vibration.vibrate(pattern: [500, 500], repeat: 0);
  }
}

void initPersistentAlert() {
  // 初始化FCM后台回调
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  // 前台消息监听
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    if (message.data['alert_type'] == 'persistent') {
      Vibration.vibrate(pattern: [500, 500], repeat: 0);
    }
  });

  // 终止状态下点击通知触发
  FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) {
    if (message != null && message.data['alert_type'] == 'persistent') {
      Vibration.vibrate(pattern: [500, 500], repeat: 0);
    }
  });
}

// 手动停止震动
void stopPersistentVibration() {
  Vibration.cancel();
}

2. 持续响铃实现

依赖配置

dependencies:
  audio_service: ^0.18.10
  just_audio: ^0.9.34
  firebase_messaging: ^14.6.1

代码逻辑

import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';
import 'package:firebase_messaging/firebase_messaging.dart';

// 后台音频任务
class PersistentRingtoneTask extends BackgroundAudioTask {
  late AudioPlayer _player;

  @override
  Future<void> onStart(Map<String, dynamic>? params) async {
    _player = AudioPlayer();
    // 加载本地铃声资源
    await _player.setAsset('assets/emergency_ringtone.mp3');
    // 设置循环播放
    await _player.setLoopMode(LoopMode.one);
    await _player.play();
  }

  @override
  Future<void> onStop() async {
    await _player.stop();
    await _player.dispose();
    await super.onStop();
  }
}

// 启动持续响铃
Future<void> startPersistentRingtone() async {
  await AudioService.start(
    backgroundTaskEntrypoint: () => AudioServiceBackground.run(() => PersistentRingtoneTask()),
    androidNotificationChannelName: '紧急提醒',
    androidNotificationIcon: 'mipmap/ic_launcher',
  );
}

// 停止响铃
Future<void> stopPersistentRingtone() async {
  await AudioService.stop();
}

// 配合FCM触发
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  if (message.data['alert_type'] == 'persistent') {
    await startPersistentRingtone();
  }
}

关键注意事项

  • 权限配置:
    • Android:需在AndroidManifest.xml中添加VIBRATE、FOREGROUND_SERVICE权限
    • iOS:需在Info.plist中配置通知权限、震动权限,后台音频播放需设置audio session为playback模式
  • 终止状态限制:iOS在完全终止状态下,仅能通过用户点击通知唤醒应用执行代码;Android可通过高优先级FCM通知触发后台回调
  • 电池优化:持续震动/响铃可能触发系统电池优化,需引导用户关闭应用的电池限制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:00:53