添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

有一次,外国客户使用我公司的手表时,反馈说Android手机在连接手表之后,别人发消息过来接收不到,经过几天的掰扯,最终写了一个demo给客户。

二、实现步骤

使用的插件和版本:flutter_notification_listener: ^1.3.2。

注意:在监听消息通知时,一定要打开对应应用的消息通知权限,否则监听不到

  1. 初始化接收端口
  2. 设置接收端口名
  3. 初始化 NotificationsListener
  4. 获取端口名
  5. 在端口的监听中进行逻辑操作
  6. 开启监听

三、代码分享

1. 安装 flutter_notification_listener

在 pubspec.yaml 文件中添加下面内容:

dependencies:
  flutter_notification_listener: ^1.3.2

2.  在 android > src > main > AndroidManifest.xml文件中注册服务

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<service android:name="im.zoe.labs.flutter_notification_listener.NotificationsHandlerService"
    android:label="Flutter Notifications Handler"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

3. 使用 flutter_notification_listener

class _NotificationPage extends State<NotificationPage> {
  int _firmwareVersion = -1;
  bool started = true;
  bool _loading = false;
  ReceivePort port = ReceivePort();
  bool hasPort = false;
  @override
  void initState() {
    super.initState();
    initPlatformState();
  /// 这里一定要是静态方法
  static void _notificationCallback(NotificationEvent evt) {
    SendPort? send = IsolateNameServer.lookupPortByName("_listener_");
    if (send == null) print("can't find the sender");
    send?.send(evt);
  Future<void> initPlatformState() async {
    if (Platform.isAndroid) {
      if (hasPort) {
        IsolateNameServer.removePortNameMapping("_listener_");
      hasPort = IsolateNameServer.registerPortWithName(port.sendPort, "_listener_");
      NotificationsListener.initialize(callbackHandle: _notificationCallback);
      port.listen((message) => onData(message));
      var isR = await NotificationsListener.isRunning;
      setState(() {
        started = isR!;
  void onData(NotificationEvent event) {
    /// 这里进行逻辑操作
    if (_firmwareVersion != -1) {
      widget.blePlugin.sendMessage(
        MessageBean(
          message: event.text.toString(),
          type: BleMessageType.qq,
          versionCode: _firmwareVersion,
          isHs: true,
          isSmallScreen: true,
  /// 开启监听
  void startListening() async {
    setState(() {
      _loading = true;
    var hasPermission = await NotificationsListener.hasPermission;
    if (!hasPermission!) {
      NotificationsListener.openPermissionSettings();
      return;
    var isR = await NotificationsListener.isRunning;
    if (!isR!) {
      await NotificationsListener.startService(
        foreground: true,
        title: "Listener Running",
        description: "Welcome to having me"
    setState(() {
      started = true;
      _loading = false;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(
              title: const Text("Notification"),
            body: Center(
                child: ListView(children: [
                  Text("firmwareVersion: $_firmwareVersion"),
                  Text("started: $started"),
                  Text("loading: $_loading"),
                  ElevatedButton(onPressed: startListening, child: const Text("start"),),
                  ElevatedButton(
                      child: const Text("queryFirmwareVersion"),
                      onPressed: () async {
                        String firmwareVersion = await widget.blePlugin.queryFirmwareVersion;
                        int index = firmwareVersion.lastIndexOf('-');
                        String subString = firmwareVersion.substring(index);
                        String version = '';
                        subString.replaceAllMapped(RegExp(r'\d'), (Match m) {
                          version += m[0]!;
                          return m[0]!;
                        setState(() {
                          _firmwareVersion = int.parse(version);
                ]))));

四、参考文案

flutter_notification_listener | Flutter Package

android_bluetooth.BluetoothLeScanner android_location.Location.distanceBetween() android_media.FaceDetector
FlutterAndroid Native原生进行混合开发(flutter module),FlutterAndroid Native相互跳转,FlutterAndroid Native进行通信的示例Demo 有Flutter官方API和引入FlutterBoost两种方式,具体可以看我的博客 第一篇 : https://blog.csdn.net/EthanCo/article/details/121394295 第二篇 : https://blog.csdn.net/EthanCo/article/details/121399323
flutter文件下载 flutter中需要页面初始化完成才能获得context,下载的监听可能因为尚未获取到context而无法刷新页面 在文件下载业务flutter中的生产者为 SendPort sendPort = IsolateNameServer.lookupPortByName("downloader_send_port"); //定义对象,并且约定名称“downloader_send_port” //广播数据 sendPort.send([id,status,progress]);`
Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知Flutter 事件与通知,Flut
1. 数据的提供者与消费者 今天想要和大家好好聊聊 ChangeNotifier 这个东西,从名字上来看它由 change(改变) 和 Notifier(通知器) 构成。打个比方: 有三个铁粉跟我说: "你发新文章的时候跟我说一声"。 之后我发布文章后,分享给了他们三个人。 很明显,这是一个 发布-订阅 模式,其中: 发布者是博主,...
import 'package:flutter/material.dart'; import 'package:flutter_imagenetwork/flutter_imagenetwork.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override
Flutter中,你可以使用`WillPopScope`来监听页面的返回操作。`WillPopScope`是一个Widget,它可以监听用户按下返回按钮或者类似的导航手势,然后执行相应的操作。 下面是一个示例代码,展示如何使用`WillPopScope`来监听页面返回: ```dart class YourPage extends StatelessWidget { @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { // 在这里执行你希望执行的操作 // 返回true表示允许返回,返回false表示阻止返回 // 例如,你可以弹出一个对话框询问用户是否确认返回 bool confirmExit = await showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: Text('确认退出?'), content: Text('确定要离开此页面吗?'), actions: [ FlatButton( child: Text('取消'), onPressed: () { Navigator.of(context).pop(false); // 阻止返回 FlatButton( child: Text('确定'), onPressed: () { Navigator.of(context).pop(true); // 允许返回 return confirmExit ?? false; // 如果对话框关闭时没有选择,则默认不允许返回 child: Scaffold( appBar: AppBar( title: Text('Your Page'), body: Center( child: Text('Your Page Content'), 在上述示例中,我们将整个页面包裹在`WillPopScope`中,并指定了`onWillPop`回调函数。在回调函数中,你可以执行任何你希望在页面返回时进行的操作。在这个示例中,我们弹出一个对话框来询问用户是否确认返回。用户的选择将决定是否允许返回。 注意:`WillPopScope`只能监听物理返回按钮或者类似的导航手势,不能监听页面中的其他返回操作,例如点击一个返回按钮。如果你想监听页面中其他返回操作,你需要手动实现相应的逻辑。