当前位置: 首页 > ai >正文

安卓app 实现监听手机app全局弹窗消息通知功能

安卓app 实现监听手机app全局弹窗消息通知功能
  1. 获取相关权限.

    try {startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
    } catch (Exception e) {startActivity(new Intent(Settings.ACTION_SETTINGS));
    }
    startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));
    
  2. 创建无障碍, 监听消息通知全局Service

    package com.yuqirong.listenwechatnotification;import android.accessibilityservice.AccessibilityService;
    import android.app.Notification;
    import android.app.PendingIntent;
    import android.os.Build;
    import android.os.Parcel;
    import android.os.Parcelable;
    import android.text.TextUtils;
    import android.view.accessibility.AccessibilityEvent;
    import android.widget.RemoteViews;import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.List;/*** Created by Anyway on 2017/2/11.*/public class WeChatAccessibilityService extends AccessibilityService {@Overridepublic void onAccessibilityEvent(AccessibilityEvent event) {if (Build.VERSION.SDK_INT < 18) {Notification notification = (Notification) event.getParcelableData();List<String> textList = getText(notification);if (textList != null && textList.size() > 0) {for (String text : textList) {if (!TextUtils.isEmpty(text)) {System.out.println(text);}break;}}}}@Overridepublic void onInterrupt() {}public List<String> getText(Notification notification) {if (null == notification) {return null;}RemoteViews views = notification.bigContentView;if (views == null) {views = notification.contentView;}if (views == null) {return null;}// Use reflection to examine the m_actions member of the given RemoteViews object.// It's not pretty, but it works.List<String> text = new ArrayList<>();try {Field field = views.getClass().getDeclaredField("mActions");field.setAccessible(true);@SuppressWarnings("unchecked")ArrayList<Parcelable> actions = (ArrayList<Parcelable>) field.get(views);// Find the setText() and setTime() reflection actionsfor (Parcelable p : actions) {Parcel parcel = Parcel.obtain();p.writeToParcel(parcel, 0);parcel.setDataPosition(0);// The tag tells which type of action it is (2 is ReflectionAction, from the source)int tag = parcel.readInt();if (tag != 2) continue;// View IDparcel.readInt();String methodName = parcel.readString();if (null == methodName) {continue;} else if (methodName.equals("setText")) {// Parameter type (10 = Character Sequence)parcel.readInt();// Store the actual stringString t = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel).toString().trim();text.add(t);}parcel.recycle();}} catch (Exception e) {e.printStackTrace();}return text;}}
    
    package com.yuqirong.listenwechatnotification;import android.annotation.TargetApi;
    import android.app.Notification;
    import android.app.PendingIntent;
    import android.os.Build;
    import android.os.Bundle;
    import android.os.Parcel;
    import android.os.Parcelable;
    import android.service.notification.NotificationListenerService;
    import android.service.notification.StatusBarNotification;
    import android.text.TextUtils;
    import android.widget.RemoteViews;import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.List;/*** Created by Anyway on 2017/2/10.*/@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    public class WeChatNotificationListenerService extends NotificationListenerService {@Overridepublic void onNotificationPosted(StatusBarNotification sbn) {// 如果该通知的包名不是微信,那么 pass 掉if (!"com.tencent.mm".equals(sbn.getPackageName())) {return;}Notification notification = sbn.getNotification();if (notification == null) {return;}PendingIntent pendingIntent = null;// 当 API > 18 时,使用 extras 获取通知的详细信息if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {Bundle extras = notification.extras;if (extras != null) {// 获取通知标题String title = extras.getString(Notification.EXTRA_TITLE, "");// 获取通知内容String content = extras.getString(Notification.EXTRA_TEXT, "");if (!TextUtils.isEmpty(content)) {System.out.println(title+":"+content);}}} else {// 当 API = 18 时,利用反射获取内容字段List<String> textList = getText(notification);if (textList != null && textList.size() > 0) {for (String text : textList) {if (!TextUtils.isEmpty(text) && text.contains("[微信红包]")) {pendingIntent = notification.contentIntent;break;}}}}// send pendingIntent to open wechattry {if (pendingIntent != null) {pendingIntent.send();}} catch (PendingIntent.CanceledException e) {e.printStackTrace();}}@Overridepublic void onNotificationRemoved(StatusBarNotification sbn) {super.onNotificationRemoved(sbn);}public List<String> getText(Notification notification) {if (null == notification) {return null;}RemoteViews views = notification.bigContentView;if (views == null) {views = notification.contentView;}if (views == null) {return null;}// Use reflection to examine the m_actions member of the given RemoteViews object.// It's not pretty, but it works.List<String> text = new ArrayList<>();try {Field field = views.getClass().getDeclaredField("mActions");field.setAccessible(true);@SuppressWarnings("unchecked")ArrayList<Parcelable> actions = (ArrayList<Parcelable>) field.get(views);// Find the setText() and setTime() reflection actionsfor (Parcelable p : actions) {Parcel parcel = Parcel.obtain();p.writeToParcel(parcel, 0);parcel.setDataPosition(0);// The tag tells which type of action it is (2 is ReflectionAction, from the source)int tag = parcel.readInt();if (tag != 2) continue;// View IDparcel.readInt();String methodName = parcel.readString();if (null == methodName) {continue;} else if (methodName.equals("setText")) {// Parameter type (10 = Character Sequence)parcel.readInt();// Store the actual stringString t = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel).toString().trim();text.add(t);}parcel.recycle();}} catch (Exception e) {e.printStackTrace();}return text;}}
    

    参考github项目, NotificationListenerService

        if (!"com.tencent.mm".equals(sbn.getPackageName())) {return;}非微信的通知, 直接返回, 不处理.if (extras != null) {// 获取通知标题String title = extras.getString(Notification.EXTRA_TITLE, "");// 获取通知内容String content = extras.getString(Notification.EXTRA_TEXT, "");if (!TextUtils.isEmpty(content)) {// 这里就可以获取到弹窗通知的头和消息题了.System.out.println(title+":"+content);}}
    

    注意: 想要获取到具体的内容, 需要到app内部消息通知开启消息详情.

  3. 声明: 本文章只做为技术分享, 切勿用于非法行为, 造成后果与本人无关

http://www.xdnf.cn/news/10896.html

相关文章:

  • git stash介绍(贮藏、暂存)(临时保存当前工作目录中尚未提交的修改)
  • 蓝桥杯国赛训练 day1
  • 6.4 note
  • c++ algorithm
  • 互联网 Web 网站
  • flex布局实现固定区域滚动
  • 贝利特价型号SPHSS03 液压伺服模块
  • maven在修改完配置之后新建项目还是不生效的原因
  • 13_pandas可视化_Matplotlib
  • Python库 Pympler 详解:内存分析与追踪工具
  • 父文档检索器引和RAG的context precision性能指标
  • docker-compose 方式搭建禅道(最新版)
  • 对接系统外部服务组件技术方案
  • 数据库包括哪些?关系型数据库是什么意思?
  • Percona Toolkit利器pt-config-diff:MySQL配置差异分析与实战指南
  • 【ROS2】各种相关概念汇总解释
  • 条形进度条
  • 【分层图 最短路 迪氏堆优化最短路】B4165 [BCSP-X 2024 12 月初中组] 贸易|普及+
  • SAP 自动编号的使用
  • 19-项目部署(Linux)
  • 爱普生Epson L3210打印机信息
  • 数据库OCP专业认证培训
  • 嵌入式笔试题+面试题
  • 佰力博科技与您探讨低温介电温谱测试仪的应用领域
  • 安全月报 | 傲盾DDoS攻击防御2025年5月简报
  • Python编程基础(四) | if语句
  • while和do-while循环
  • Office文档图片批量导出工具
  • 30天速通C++(九):深入理解deque
  • CppCon 2014 学习:Anatomy of a Smart Pointer