一、需求背景
有一次,外国客户使用我公司的手表时,反馈说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);
});
}),
]))));
}
}