有一次,外国客户使用我公司的手表时,反馈说Android手机在连接手表之后,别人发消息过来接收不到,经过几天的掰扯,最终写了一个demo给客户。
二、实现步骤
使用的插件和版本:flutter_notification_listener: ^1.3.2。
注意:在监听消息通知时,一定要打开对应应用的消息通知权限,否则监听不到
-
初始化接收端口
-
设置接收端口名
-
初始化 NotificationsListener
-
获取端口名
-
在端口的监听中进行逻辑操作
-
开启监听
三、代码分享
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
Flutter与Android Native原生进行混合开发(flutter module),Flutter和Android Native相互跳转,Flutter和Android 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. 数据的提供者与消费者
今天想要和大家好好聊聊 Change
Notifier 这个东西,从名字上来看它由 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`只能监听物理返回按钮或者类似的导航手势,不能监听页面中的其他返回操作,例如点击一个返回按钮。如果你想监听页面中其他返回操作,你需要手动实现相应的逻辑。