jiusanzhou / flutter_notification_listener

Flutter plugin to listen for and interact with all incoming notifications for Android. 一个监听手机通知的插件。
https://pub.dev/packages/flutter_notification_listener
Other
36 stars 38 forks source link

Multiple Notfications #15

Closed akhilgorantala closed 2 years ago

akhilgorantala commented 2 years ago

can u please tell me how to use only the data single time, it is repeating every time.

Screenshot 2022-05-06 150909 Screenshot 2022-05-06 152150

Screenshot 2022-05-06 152627 am trying to send the data only single time to an api.

jiusanzhou commented 2 years ago

Hi @akhilgorantala , which version of this plugin do you use? The log should be break lines, can't get full event fields from your screenshots.

I don't know this app, so I can't debug for you. But you can offer more information about the event data.

ZiaUrRahmam commented 2 years ago

@akhilgorantala please confirm us about your issue: 1.You are getting each notification for more than one time? 2.You want to get only one out of reptitive notifications? Is this your main issue or something else? if this one is the issue then please tell us which apps notifications are you trying to get. also show us an example that matches your situation so that we can help you in a better way.

akhilgorantala commented 2 years ago

The 2nd point i ant to get only one data out of repeated notification but the both notifications has same id and unique id. @jiusanzhou the latest one.

Check this: WhatsApp Image 2022-05-04 at 4 29 48 PM WhatsApp Image 2022-05-04 at 4 29 49 PM WhatsApp Image 2022-05-04 at 4 29 49 PM (1) WhatsApp Image 2022-05-04 at 4 29 50 PM

i want to send the data to api. but its repeating there too. Screenshot 2022-05-06 152627

jiusanzhou commented 2 years ago

I'm not sure the behaviors of your phonepe app. I'm guessing the first one is removed when the second duplicate notification is sent. Please checkout the log in android filter with NotificationsListenerService, content like notification removed: xxxx.

Logs are better than screenshots! Please provide some logs with full information.

Maybe flutter_notification_listener supports the onNotificationRemoved and notify the flutter, that can solve your issue.

akhilgorantala commented 2 years ago

if i remove the notification am getting the notification removed id until it not showing anything. i tried so many different combination but am still getting the 2 alerts.

akhilgorantala commented 2 years ago

how can we take the data and remove the notification immediately, for a specific app. is this possible ?

jiusanzhou commented 2 years ago

In the android studio use send evt to ui to filter logs, I need to see your logs.

For example,

2022-05-06 19:34:08.112 8575-8605/im.zoe.labs.flutter_notification_listener_example I/flutter: send evt to ui: {"infoText":null,"canTap":true,"title":"Me","subText":null,"uid":10313,"showWhen":true,"package_name":"com.whatsapp","text":"Sorry","id":1,"_id":"3e5de21dece9a","actions":[{"semantic":1,"inputs":[{"label":"回复","key":"direct_reply_input"}],"id":0,"title":"回复"},{"semantic":2,"inputs":[],"id":1,"title":"标记为已读"}],"channelId":"individual_chat_defaults_1","key":"0|com.whatsapp|1|rFtCg9OMAw+rJZgOBis3p2KY3oOsOwCMOevDMZJ2PeE=\n|10313","timestamp":1651836847770,"hasLargeIcon":true}
2022-05-06 19:34:08.117 8575-8605/im.zoe.labs.flutter_notification_listener_example I/flutter: send evt to ui: {"infoText":null,"canTap":true,"title":"Me","subText":null,"uid":10313,"showWhen":true,"package_name":"com.whatsapp","text":"Sorry","id":1,"_id":"2944b2311c179","actions":null,"channelId":"individual_chat_defaults_1","key":"0|com.whatsapp|1|null|10313","timestamp":1651836847773,"hasLargeIcon":false}

how can we take the data and remove the notification immediately, for a specific app. is this possible ?

Check out the methods section of Object NotificationEvent. Invoking event.tap() can remove the notification in most cases. But removing notification won't fix your problem.

akhilgorantala commented 2 years ago

D/NotificationsListenerService(16465): send event to flutter side immediately! D/NotificationsListenerService(16465): send notification event: {infoText=null, canTap=true, title=Denny: Denny, subText=null, uid=10247, showWhen=true, largeIcon=[B@c20a064, package_name=com.phonepe.app, text=₹1 has been sent to Me., id=618833626, _id=ced748bda4d4b, actions=[{semantic=0, inputs=[], id=0, title=Mark as Read}, {semantic=0, inputs=[{label=Reply, key=remote_input_reply}], id=1, title=Reply}], channelId=PHONEPE_CHAT_CHANNEL_ID, key=0|com.phonepe.app|618833626|null|10247, timestamp=1651840128592} I/flutter (16465): send evt to ui: {"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651840128592,"hasLargeIcon":true} I/flutter (16465): old:{"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to you.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651840004305,"hasLargeIcon":true} I/flutter (16465): New:{"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651840128592,"hasLargeIcon":true} V/AutofillManager(16465): requestHideFillUi(null): anchor = null V/AutofillManager(16465): requestHideFillUi(null): anchor = null V/AutofillManager(16465): requestHideFillUi(null): anchor = null D/NotificationsListenerService(16465): send event to flutter side immediately! D/NotificationsListenerService(16465): send notification event: {infoText=null, canTap=true, title=Denny: Denny, subText=null, uid=10247, showWhen=true, largeIcon=[B@e795ed0, package_name=com.phonepe.app, text=₹1 has been sent to Me., id=618833626, _id=ced748bda4d4b, actions=[{semantic=0, inputs=[], id=0, title=Mark as Read}, {semantic=0, inputs=[{label=Reply, key=remote_input_reply}], id=1, title=Reply}], channelId=PHONEPE_CHAT_CHANNEL_ID, key=0|com.phonepe.app|618833626|null|10247, timestamp=1651840186901} I/flutter (16465): send evt to ui: {"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651840186901,"hasLargeIcon":true} I/flutter (16465): old:{"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651840128592,"hasLargeIcon":true} I/flutter (16465): New:{"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651840186901,"hasLargeIcon":true}

jiusanzhou commented 2 years ago

The phonepe send 2 same notifications, it's so weird. I need 2 more infos:

  1. Do notifications of different messages have the same uniqueId?
  2. Try calling event.getFull() to get original object to find the difference from notifications of 1 message. you can paste in this thread
akhilgorantala commented 2 years ago

Point 1: uniqueId is same for every notification of "Name1" and its different with compared to "Name2" and "Name3" etc. (every unique name has its own uniqueID)

Point 2: can u please tell me how to call the getFull().

jiusanzhou commented 2 years ago

So, your work with notifications of phoneap, there are 2 problems:

Obviously, they are bad implementation of android notifications.

We need to solve this problem by some tricks way.


  var caches = Map<String, NotificationEvent>();

  // Adjust the gap according to the actual situation
  bool isDuplicate(NotificationEvent evt, {int gap = 100}) {
    var last = caches[evt.uniqueId];
    caches[evt.uniqueId] = evt;

    if (last == null) {
      return false;
    }

    return evt.timestamp - last.timestamp < gap;
  }

  void onData(NotificationEvent event) {
    if (isDuplicate(event)) {
      // ignore duplicate event
      return;
    }

    setState(() {
      _log.add(event);
    });

    print(event.toString());
  }

Need to clean up old events regularly to avoid caches taking up too much memory!

@akhilgorantala


can u please tell me how to call the getFull().

  1. update package to the latest version
  2. just invoke getFull of the NotificationEvent object
akhilgorantala commented 2 years ago

Obviously, they are bad implementation of android notifications.

yes, is there any way for this type of notifications.

jiusanzhou commented 2 years ago

yes, is there any way for this type of notifications.

Please see code in previous comment.

akhilgorantala commented 2 years ago

yes, is there any way for this type of notifications.

Please see code in previous comment.

can u please explain how it works.

ZiaUrRahmam commented 2 years ago

@jiusanzhou @akhilgorantala as far as i think this problem can be solved without using Id's Please use the following snippet and do let me know if it works or not

void onData(NotificationEvent evt) {
  if (evt.raw!['textLines'] == null && evt.largeIcon != null) {
      print(evt.toString());
    }
}

This filter will give only one output notification. Note I have tested it with whatsapp and its working fine.

akhilgorantala commented 2 years ago

@ZiaUrRahmam it's working but within 2 mins i got notification again. Is there any solution for this ? (Check the time stamp once)IMG_20220506_214013.jpg

ZiaUrRahmam commented 2 years ago

@ZiaUrRahmam it's working but within 2 mins i got notification again. Is there any solution for this ?

This is the reason i asked you many times plz provide an examplary code that shows how you are working. I n my case m not receiving the same notification after 2 mnts So there is a mistake in your implication. I can only help if i know how you are trying to implement.

akhilgorantala commented 2 years ago

Please check it once. `void onData(NotificationEvent event) { if (event.raw['textLines'] == null && event.largeIcon != null) { print('Raw' + event.toString()); }

if (event.packageName.contains('com.google.android.apps.nbu.paisa.user')) {
  var gpayAmount = event.title.toString();
  var gpaySenderName = event.title.toString();
  //gpay amount
  const start = '₹';
  const end = '.00';
  final startIndex = gpayAmount.indexOf(start);
  final endIndex = gpayAmount.indexOf(end, startIndex + start.length);
  gpayAmount = gpayAmount
      .substring(startIndex + start.length, endIndex)
      .replaceAll(',', '');
  //gpay sender name
  gpaySenderName = gpaySenderName.split(' paid').first;
  //gpap sender message
  var gpayMessage = event.text.toString();
  if (gpayMessage == 'Tap to view.') {
    gpayMessage = '';
  } else {
    //send message
  }
  postData('1', gpayAmount, 'GPay', gpayMessage, gpaySenderName, '1');
} else if (event.packageName.contains('com.phonepe.app')) {
  //phonepe amount
  var phonepeAmount = event.text.toString();
  phonepeAmount = phonepeAmount.split(' has been sent to').first;
  phonepeAmount = phonepeAmount.split('₹').last;
  //phonepe name
  var phonepeName = event.title.toString();
  phonepeName = phonepeName.split(': ').last;
  postData('1', phonepeAmount, 'PhonePe', '', phonepeName, '1');
} else if (event.packageName.contains('net.one97.paytm')) {
} else if (event.packageName.contains('com.paytm.business')) {
} else if (event.packageName.contains('in.org.npci.upiapp')) {
} else if (event.packageName.contains('com.phonepe.app.business')) {
} else if (event.packageName
    .contains('com.google.android.apps.nbu.paisa.merchant')) {
} else if (event.packageName.contains('com.bharatpe.app')) {
} else if (event.packageName
    .contains('im.zoe.labs.flutter_notification_listener_example')) {
  var streamAlertAmount = event.text.toString();
  streamAlertAmount =
      streamAlertAmount.split('Stream Alert paid you ₹').last;
  postData(
      '1', streamAlertAmount, 'Stream Alert', 'Hello', 'Stream Alert', '0');
} else {
  print('ignored');
}

setState(() {
  _log.add(event);
});

}`

ZiaUrRahmam commented 2 years ago

run this code by placing in your main.dart file and let me know if it works or not. Please do not change it for proper testing except pkg name. Focus on onData method and you can also change your pkg name for testing and then do let me know.


import 'dart:isolate';
import 'dart:typed_data';

import 'dart:ui';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter_notification_listener/flutter_notification_listener.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: NotificationsLog(),
    );
  }
}

class NotificationsLog extends StatefulWidget {
  const NotificationsLog({Key? key}) : super(key: key);

  @override
  _NotificationsLogState createState() => _NotificationsLogState();
}

class _NotificationsLogState extends State<NotificationsLog> {
  List<NotificationEvent> _log = [];
  bool started = false;
  bool _loading = false;

  ReceivePort port = ReceivePort();

  @override
  void initState() {
    initPlatformState();
    super.initState();
  }

  static void _callback(NotificationEvent evt) {
    final SendPort? send = IsolateNameServer.lookupPortByName("_listener_");
    if (send == null) print("can't find the sender");
    send?.send(evt);
  }

  Future<void> initPlatformState() async {
    NotificationsListener.initialize(callbackHandle: _callback);
    IsolateNameServer.removePortNameMapping("_listener_");
    IsolateNameServer.registerPortWithName(port.sendPort, "_listener_");
    port.listen((message) => onData(message));
    var isR = await NotificationsListener.isRunning;
    print("""Service is ${!isR! ? "not " : ""}aleary running""");

    setState(() {
      started = isR;
    });
  }

  void onData(NotificationEvent evt) {

    if (!evt.packageName!.contains("com.google.android.apps.nbu.paisa.user") &&///use here your pkg name
        evt.raw!['textLines'] == null &&
        evt.largeIcon != null) {
      setState(() {
        if (!_log.contains(evt)) _log.add(evt);
      });
    }
  }

  void startListening() async {
    print("start listening");
    setState(() {
      _loading = true;
    });
    var hasPermission = await NotificationsListener.hasPermission;
    if (!hasPermission!) {
      print("no permission, so open settings");
      NotificationsListener.openPermissionSettings();
      return;
    }

    var isR = await NotificationsListener.isRunning;

    if (!isR!) {
      await NotificationsListener.startService(foreground: false);
    }

    setState(() {
      started = true;
      _loading = false;
    });
  }

  void stopListening() async {
    print("stop listening");

    setState(() {
      _loading = true;
    });

    await NotificationsListener.stopService();

    setState(() {
      started = false;
      _loading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Notifications Listener Example'),
      ),
      body: Center(
          child: ListView.builder(
              itemCount: _log.length,
              reverse: true,
              itemBuilder: (BuildContext context, int idx) {
                final entry = _log[idx];
                return ListTile(
                    trailing: entry.hasLargeIcon!
                        ? Image.memory(entry.largeIcon!)
                        : Text(entry.packageName.toString().split('.').last),
                    title: Container(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(entry.text!),
                        ],
                      ),
                    ));
              })),
      floatingActionButton: FloatingActionButton(
        onPressed: started ? stopListening : startListening,
        tooltip: 'Start/Stop sensing',
        child: _loading
            ? const Icon(Icons.close)
            : (started ? const Icon(Icons.stop) : const Icon(Icons.play_arrow)),
      ),
    );
  }
}
akhilgorantala commented 2 years ago

D/NotificationsListenerService(30802): send event to flutter side immediately! D/NotificationsListenerService(30802): send notification event: {infoText=null, canTap=true, title=Denny: Denny, subText=null, uid=10247, showWhen=true, largeIcon=[B@53e9f4a, package_name=com.phonepe.app, text=₹2 has been sent to Me., id=618833626, _id=ced748bda4d4b, actions=[{semantic=0, inputs=[], id=0, title=Mark as Read}, {semantic=0, inputs=[{label=Reply, key=remote_input_reply}], id=1, title=Reply}], channelId=PHONEPE_CHAT_CHANNEL_ID, key=0|com.phonepe.app|618833626|null|10247, timestamp=1651854676512} I/flutter (30802): send evt to ui: {"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹2 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651854676512,"hasLargeIcon":true} I/flutter (30802): Raw{"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹2 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651854676512,"hasLargeIcon":true} D/NotificationsListenerService(30802): send event to flutter side immediately! D/NotificationsListenerService(30802): send notification event: {infoText=null, canTap=true, title=Denny: Denny, subText=null, uid=10247, showWhen=true, largeIcon=[B@84f6616, package_name=com.phonepe.app, text=₹2 has been sent to Me., id=618833626, _id=ced748bda4d4b, actions=[{semantic=0, inputs=[], id=0, title=Mark as Read}, {semantic=0, inputs=[{label=Reply, key=remote_input_reply}], id=1, title=Reply}], channelId=PHONEPE_CHAT_CHANNEL_ID, key=0|com.phonepe.app|618833626|null|10247, timestamp=1651854681105} I/flutter (30802): send evt to ui: {"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹2 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651854681105,"hasLargeIcon":true} I/flutter (30802): Raw{"infoText":null,"canTap":true,"title":"Denny: Denny","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹2 has been sent to Me.","id":618833626,"_id":"ced748bda4d4b","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|618833626|null|10247","timestamp":1651854681105,"hasLargeIcon":true}

Now i got this in milli seconds

akhilgorantala commented 2 years ago

run this code by placing in your main.dart file and let me know if it works or not. Please do not change it for proper testing except pkg name. Focus on onData method and you can also change your pkg name for testing and then do let me know.


import 'dart:isolate';
import 'dart:typed_data';

import 'dart:ui';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter_notification_listener/flutter_notification_listener.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: NotificationsLog(),
    );
  }
}

class NotificationsLog extends StatefulWidget {
  const NotificationsLog({Key? key}) : super(key: key);

  @override
  _NotificationsLogState createState() => _NotificationsLogState();
}

class _NotificationsLogState extends State<NotificationsLog> {
  List<NotificationEvent> _log = [];
  bool started = false;
  bool _loading = false;

  ReceivePort port = ReceivePort();

  @override
  void initState() {
    initPlatformState();
    super.initState();
  }

  static void _callback(NotificationEvent evt) {
    final SendPort? send = IsolateNameServer.lookupPortByName("_listener_");
    if (send == null) print("can't find the sender");
    send?.send(evt);
  }

  Future<void> initPlatformState() async {
    NotificationsListener.initialize(callbackHandle: _callback);
    IsolateNameServer.removePortNameMapping("_listener_");
    IsolateNameServer.registerPortWithName(port.sendPort, "_listener_");
    port.listen((message) => onData(message));
    var isR = await NotificationsListener.isRunning;
    print("""Service is ${!isR! ? "not " : ""}aleary running""");

    setState(() {
      started = isR;
    });
  }

  void onData(NotificationEvent evt) {

    if (!evt.packageName!.contains("com.google.android.apps.nbu.paisa.user") &&///use here your pkg name
        evt.raw!['textLines'] == null &&
        evt.largeIcon != null) {
      setState(() {
        if (!_log.contains(evt)) _log.add(evt);
      });
    }
  }

  void startListening() async {
    print("start listening");
    setState(() {
      _loading = true;
    });
    var hasPermission = await NotificationsListener.hasPermission;
    if (!hasPermission!) {
      print("no permission, so open settings");
      NotificationsListener.openPermissionSettings();
      return;
    }

    var isR = await NotificationsListener.isRunning;

    if (!isR!) {
      await NotificationsListener.startService(foreground: false);
    }

    setState(() {
      started = true;
      _loading = false;
    });
  }

  void stopListening() async {
    print("stop listening");

    setState(() {
      _loading = true;
    });

    await NotificationsListener.stopService();

    setState(() {
      started = false;
      _loading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Notifications Listener Example'),
      ),
      body: Center(
          child: ListView.builder(
              itemCount: _log.length,
              reverse: true,
              itemBuilder: (BuildContext context, int idx) {
                final entry = _log[idx];
                return ListTile(
                    trailing: entry.hasLargeIcon!
                        ? Image.memory(entry.largeIcon!)
                        : Text(entry.packageName.toString().split('.').last),
                    title: Container(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(entry.text!),
                        ],
                      ),
                    ));
              })),
      floatingActionButton: FloatingActionButton(
        onPressed: started ? stopListening : startListening,
        tooltip: 'Start/Stop sensing',
        child: _loading
            ? const Icon(Icons.close)
            : (started ? const Icon(Icons.stop) : const Icon(Icons.play_arrow)),
      ),
    );
  }
}

It's working for what'sapp but not the the payment app. IMG_20220506_223032.jpg

akhilgorantala commented 2 years ago

I think if we clear the notification after listening will work. @ZiaUrRahmam (do u have any idea about this.)

ZiaUrRahmam commented 2 years ago

I think if we clear the notification after listening will work. @ZiaUrRahmam

Share the log details (for payment app only) after onData Directly print the event without any filters and if then conditions Then share full log with multiple notifications for a single notification. So that i can lookup for a trick

akhilgorantala commented 2 years ago

I/flutter (28635): Raw{"infoText":null,"canTap":true,"title":"ALAJPURI KRISHNA: ALAJPURI KRISHNA","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Unknown.","id":1852482137,"_id":"a7c1908ca97f3","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|1852482137|null|10247","timestamp":1651861428690,"hasLargeIcon":true} I/flutter (28635): Raw{"infoText":null,"canTap":true,"title":"ALAJPURI KRISHNA: ALAJPURI KRISHNA","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Me.","id":1852482137,"_id":"a7c1908ca97f3","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|1852482137|null|10247","timestamp":1651861429666,"hasLargeIcon":true}

akhilgorantala commented 2 years ago

Full Log

D/NotificationsListenerService(28635): send event to flutter side immediately! D/NotificationsListenerService(28635): send notification event: {infoText=null, canTap=true, title=ALAJPURI KRISHNA: ALAJPURI KRISHNA, subText=null, uid=10247, showWhen=true, largeIcon=[B@d659bdd, package_name=com.phonepe.app, text=₹1 has been sent to Unknown., id=1852482137, _id=a7c1908ca97f3, actions=[{semantic=0, inputs=[], id=0, title=Mark as Read}, {semantic=0, inputs=[{label=Reply, key=remote_input_reply}], id=1, title=Reply}], channelId=PHONEPE_CHAT_CHANNEL_ID, key=0|com.phonepe.app|1852482137|null|10247, timestamp=1651861428690} I/flutter (28635): send evt to ui: {"infoText":null,"canTap":true,"title":"ALAJPURI KRISHNA: ALAJPURI KRISHNA","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Unknown.","id":1852482137,"_id":"a7c1908ca97f3","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|1852482137|null|10247","timestamp":1651861428690,"hasLargeIcon":true} I/flutter (28635): Raw{"infoText":null,"canTap":true,"title":"ALAJPURI KRISHNA: ALAJPURI KRISHNA","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Unknown.","id":1852482137,"_id":"a7c1908ca97f3","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|1852482137|null|10247","timestamp":1651861428690,"hasLargeIcon":true} D/NotificationsListenerService(28635): send event to flutter side immediately! D/NotificationsListenerService(28635): send notification event: {infoText=null, canTap=true, title=ALAJPURI KRISHNA: ALAJPURI KRISHNA, subText=null, uid=10247, showWhen=true, largeIcon=[B@fa518d9, package_name=com.phonepe.app, text=₹1 has been sent to Me., id=1852482137, _id=a7c1908ca97f3, actions=[{semantic=0, inputs=[], id=0, title=Mark as Read}, {semantic=0, inputs=[{label=Reply, key=remote_input_reply}], id=1, title=Reply}], channelId=PHONEPE_CHAT_CHANNEL_ID, key=0|com.phonepe.app|1852482137|null|10247, timestamp=1651861429666} I/flutter (28635): send evt to ui: {"infoText":null,"canTap":true,"title":"ALAJPURI KRISHNA: ALAJPURI KRISHNA","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Me.","id":1852482137,"_id":"a7c1908ca97f3","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|1852482137|null|10247","timestamp":1651861429666,"hasLargeIcon":true} I/flutter (28635): Raw{"infoText":null,"canTap":true,"title":"ALAJPURI KRISHNA: ALAJPURI KRISHNA","subText":null,"uid":10247,"showWhen":true,"package_name":"com.phonepe.app","text":"₹1 has been sent to Me.","id":1852482137,"_id":"a7c1908ca97f3","actions":[{"semantic":0,"inputs":[],"id":0,"title":"Mark as Read"},{"semantic":0,"inputs":[{"label":"Reply","key":"remote_input_reply"}],"id":1,"title":"Reply"}],"channelId":"PHONEPE_CHAT_CHANNEL_ID","key":"0|com.phonepe.app|1852482137|null|10247","timestamp":1651861429666,"hasLargeIcon":true}

jiusanzhou commented 2 years ago

@akhilgorantala Have you tried this method?

akhilgorantala commented 2 years ago

@akhilgorantala Have you tried this method?

I will try it max number of transactions complete, @jiusanzhou @ZiaUrRahmam do u have any idea how to save the received data into two different variables.

akhilgorantala commented 2 years ago

@akhilgorantala Have you tried this method?

its not working i tried it

jiusanzhou commented 2 years ago

@akhilgorantala Have you tried this method?

its not working i tried it

Adjust the gap according to the actual situation, default gap=100 maybe is too small.

akhilgorantala commented 2 years ago

@jiusanzhou @ZiaUrRahmam onData function is called two times even i get one notification.

akhilgorantala commented 2 years ago

In the android studio use send evt to ui to filter logs, I need to see your logs.

For example,

2022-05-06 19:34:08.112 8575-8605/im.zoe.labs.flutter_notification_listener_example I/flutter: send evt to ui: {"infoText":null,"canTap":true,"title":"Me","subText":null,"uid":10313,"showWhen":true,"package_name":"com.whatsapp","text":"Sorry","id":1,"_id":"3e5de21dece9a","actions":[{"semantic":1,"inputs":[{"label":"回复","key":"direct_reply_input"}],"id":0,"title":"回复"},{"semantic":2,"inputs":[],"id":1,"title":"标记为已读"}],"channelId":"individual_chat_defaults_1","key":"0|com.whatsapp|1|rFtCg9OMAw+rJZgOBis3p2KY3oOsOwCMOevDMZJ2PeE=\n|10313","timestamp":1651836847770,"hasLargeIcon":true}
2022-05-06 19:34:08.117 8575-8605/im.zoe.labs.flutter_notification_listener_example I/flutter: send evt to ui: {"infoText":null,"canTap":true,"title":"Me","subText":null,"uid":10313,"showWhen":true,"package_name":"com.whatsapp","text":"Sorry","id":1,"_id":"2944b2311c179","actions":null,"channelId":"individual_chat_defaults_1","key":"0|com.whatsapp|1|null|10313","timestamp":1651836847773,"hasLargeIcon":false}

how can we take the data and remove the notification immediately, for a specific app. is this possible ?

Check out the methods section of Object NotificationEvent. Invoking event.tap() can remove the notification in most cases. But removing notification won't fix your problem.

event.tap() is opening the related app. How can we remove the notification, without opening the app.

jiusanzhou commented 2 years ago

I think that is not possible in normal.

BTW, I was working on a new plugin https://github.com/jiusanzhou/flutter_floatwing , give a star if you guys like it.

ZiaUrRahmam commented 2 years ago

BTW, I was working on a new plugin https://github.com/jiusanzhou/flutter_floatwing , give a star if you guys like it

Done.

farisk218 commented 6 months ago

@jiusanzhou This duplication issue is not fixed, right?