| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- import 'dart:async';
- import 'dart:isolate';
- import 'dart:math';
- import 'dart:ui';
- import 'package:fast_gbk/fast_gbk.dart';
- import 'package:flutter/material.dart';
- import 'package:mqtt_client/mqtt_client.dart';
- import 'package:mqtt_client/mqtt_server_client.dart';
- import 'package:flutter_notification_listener/flutter_notification_listener.dart';
- import 'package:uuid/uuid.dart';
- Future<void> main() async {
- runApp(const MyApp());
- }
- class MyApp extends StatelessWidget {
- const MyApp({super.key});
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- title: 'MokiBox',
- theme: ThemeData(
- primarySwatch: Colors.blue,
- ),
- home: const MyHomePage(title: 'Moki收款宝'),
- );
- }
- }
- class Listener {
- Mqtt mqtt = Mqtt();
- Listener() {
- initPlatformState();
- }
- @pragma('vm:entry-point')
- static void _callback(NotificationEvent evt) {
- final SendPort? send =
- IsolateNameServer.lookupPortByName("notifications_send_port");
- if (send == null) print("can't find the sender");
- send?.send(evt);
- }
- void testSendMsg() {
- String msg =
- "{\"type\":\"tts_dynamic\",\"msgid\":\"${Random().nextInt(999999)}\",\"txt\":\"设备已连接!\"}";
- mqtt.sendMsg(msg);
- }
- void onData(NotificationEvent event) {
- String? msg;
- if (event.packageName == 'com.eg.android.AlipayGphone' &&
- event.title == '店员通') {
- msg = event.text;
- if (msg == null) return;
- final number = RegExp(r'\d+\.\d+').firstMatch(msg);
- final orderId = Random().nextInt(999999);
- if (number != null) {
- final regAmount = double.parse(number.group(0)!);
- String amount = regAmount.toStringAsFixed(2);
- if (amount.endsWith('.00')) {
- amount = amount.replaceAll('.00', '');
- }
- String msgPush = '866374061547503|1007-2|$orderId|2001|$amount|7571';
- mqtt.sendMsg(msgPush);
- }
- }
- if (event.packageName == 'com.tencent.mm' && event.title == '微信收款助手') {
- msg = event.text;
- if (msg == null) return;
- final number = RegExp(r'\d+\.\d+').firstMatch(msg);
- final orderId = Random().nextInt(999999);
- if (number != null) {
- final regAmount = double.parse(number.group(0)!);
- String amount = regAmount.toStringAsFixed(2);
- if (amount.endsWith('.00')) {
- amount = amount.replaceAll('.00', '');
- }
- String msgPush = '866374061547503|1007-2|$orderId|2003|$amount|7571';
- mqtt.sendMsg(msgPush);
- }
- }
- }
- // 监听到消息后转到处理函数
- Future<void> initPlatformState() async {
- NotificationsListener.initialize(callbackHandle: _callback);
- // register you event handler in the ui logic.
- NotificationsListener.receivePort?.listen((evt) => onData(evt));
- }
- void startListening() async {
- print("start listening");
- var isR = await NotificationsListener.isRunning;
- if (!isR!) {
- await NotificationsListener.startService();
- }
- }
- Future<void> checkPermission() async {
- var hasPermission = await NotificationsListener.hasPermission;
- if (!hasPermission!) {
- print("no permission, so open settings");
- NotificationsListener.openPermissionSettings();
- return;
- }
- }
- }
- class Mqtt {
- late MqttServerClient client;
- Mqtt() {
- connect();
- }
- Future<MqttServerClient> connect() async {
- var uuid = const Uuid();
- client = MqttServerClient.withPort('47.92.50.210', uuid.v4(), 9883);
- client.logging(on: true);
- String willMsg =
- "{\"type\":\"tts_dynamic\",\"msgid\":\"${Random().nextInt(999999)}\",\"txt\":\"lost connect!\"}";
- final connMessage = MqttConnectMessage()
- .authenticateAs('moki', 'Moki@886.')
- .withWillTopic('866374061547503')
- .withWillMessage(willMsg)
- .startClean() // 清理会话
- .withWillQos(MqttQos.atLeastOnce);
- client.connectionMessage = connMessage;
- client.autoReconnect = true;
- client.keepAlivePeriod = 120;
- try {
- await client.connect();
- } catch (e) {
- print('Exception: $e');
- client.disconnect();
- }
- return client;
- }
- Future<String> sendMsg(String msg) async {
- // 发布消息
- final builder = MqttClientPayloadBuilder();
- // builder.addString(msg);
- final bytes = gbk.encode(msg);
- for (var element in bytes) {
- builder.addByte(element);
- }
- // MqttServerClient client = await connect();
- client.publishMessage(
- '866374061547503', MqttQos.atLeastOnce, builder.payload!);
- return 'success';
- }
- // // 断开连接
- // await
- //
- // client.disconnect();
- }
- class MyHomePage extends StatefulWidget {
- const MyHomePage({Key? key, required this.title}) : super(key: key);
- final String title;
- @override
- State<StatefulWidget> createState() => _MyHomePageState();
- }
- class _MyHomePageState extends State<MyHomePage> {
- late Listener listener = Listener();
- // 弹框信息
- void _showDialog(BuildContext context, String msg, bool tag) {
- String title = tag ? '成功!' : '失败';
- showDialog(
- context: context,
- builder: (BuildContext context) {
- return Theme(
- data: Theme.of(context).copyWith(
- dialogTheme: DialogTheme(
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(5.0)))),
- child: AlertDialog(
- title: Text(title),
- content: Text(msg),
- actions: <Widget>[
- TextButton(
- child: const Center(child: Text('确定')),
- onPressed: () {
- Navigator.of(context).pop();
- },
- ),
- ],
- ));
- },
- );
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text(widget.title),
- backgroundColor: Colors.cyan,
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- const Text(
- '欢迎使用魔基盒收款宝',
- style: TextStyle(
- fontSize: 22, // 设置字体大小为20
- ),
- textAlign: TextAlign.center,
- ),
- const Text(
- '请依次点击如下按钮!',
- style: TextStyle(
- fontSize: 16, // 设置字体大小为20
- ),
- textAlign: TextAlign.center,
- ),
- ElevatedButton.icon(
- icon: const Icon(Icons.ad_units_outlined),
- label: const Text("申请权限"),
- style: ElevatedButton.styleFrom(
- foregroundColor: Colors.white,
- backgroundColor: Colors.cyan,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(5), // 设置按钮的圆角半径为10
- ),
- ),
- onPressed: () async {
- listener.checkPermission();
- },
- ),
- ElevatedButton.icon(
- icon: const Icon(Icons.add_chart_rounded),
- onPressed: () async {
- listener.startListening();
- _showDialog(context, '服务已成功启动!', true);
- },
- label: const Text('开启监听'),
- style: ElevatedButton.styleFrom(
- foregroundColor: Colors.white,
- backgroundColor: Colors.greenAccent,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(5), // 设置按钮的圆角半径为10
- ),
- ),
- ),
- ElevatedButton.icon(
- icon: const Icon(Icons.add_alert_outlined),
- onPressed: () async {
- listener.testSendMsg();
- },
- label: const Text('检测设备'),
- style: ElevatedButton.styleFrom(
- foregroundColor: Colors.white,
- backgroundColor: Colors.grey,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(5), // 设置按钮的圆角半径为10
- ),
- ),
- )
- ],
- ),
- ),
- );
- }
- }
|