实例介绍
微信聊天界面的布局,查看方法:
AndroidStudio--Tools--Android--Android Device Monitor
【实例截图】
【核心代码】
public class WeChatLogService extends AccessibilityService { /** * 聊天对象 */ private String ChatName; /** * 聊天最新一条记录 */ private String ChatRecord = "cxk"; /** * 小视频的秒数,格式为00:00 */ private String VideoSecond; @Override public void onAccessibilityEvent(AccessibilityEvent event) { int eventType = event.getEventType(); switch (eventType) { //每次在聊天界面中有新消息到来时都出触发该事件 case AccessibilityEvent.TYPE_VIEW_SCROLLED: //获取当前聊天页面的根布局 AccessibilityNodeInfo rootNode = getRootInActiveWindow(); //获取聊天信息 getWeChatLog(rootNode); break; } } /** * 遍历所有控件获取聊天信息 * * @param rootNode */ private void getWeChatLog(AccessibilityNodeInfo rootNode) { if (rootNode != null) { //获取所有聊天的线性布局 List<AccessibilityNodeInfo> listChatRecord = rootNode.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/p"); if (listChatRecord.size() == 0) { return; } //获取最后一行聊天的线性布局(即是最新的那条消息) AccessibilityNodeInfo finalNode = listChatRecord.get(listChatRecord.size() - 1); //获取聊天对象 GetChatName(finalNode); //获取聊天内容 GetChatRecord(finalNode); } } /** * 遍历所有控件,找到头像Imagview,里面有对联系人的描述 */ private void GetChatName(AccessibilityNodeInfo node) { for (int i = 0; i < node.getChildCount(); i ) { AccessibilityNodeInfo node1 = node.getChild(i); if ("android.widget.ImageView".equals(node1.getClassName()) && node1.isClickable()) { //获取聊天对象,这里两个if是为了确定找到的这个ImageView是头像的 if (!TextUtils.isEmpty(node1.getContentDescription())) { ChatName = node1.getContentDescription().toString(); if (ChatName.contains("头像")) { ChatName = ChatName.replace("头像", ""); } } } GetChatName(node1); } } /** * 遍历所有控件:这里分四种情况 * 文字聊天: 一个TextView,并且他的父布局是android.widget.RelativeLayout * 语音的秒数: 一个TextView,并且他的父布局是android.widget.RelativeLayout,但是他的格式是0"的格式,所以可以通过这个来区分 * 图片:一个ImageView,并且他的父布局是android.widget.FrameLayout,描述中包含“图片”字样(发过去的图片),发回来的图片现在还无法监听 * 表情:也是一个ImageView,并且他的父布局是android.widget.LinearLayout * 小视频的秒数:一个TextView,并且他的父布局是android.widget.FrameLayout,但是他的格式是00:00"的格式,所以可以通过这个来区分 * * @param node */ public void GetChatRecord(AccessibilityNodeInfo node) { for (int i = 0; i < node.getChildCount(); i ) { AccessibilityNodeInfo nodeChild = node.getChild(i); //聊天内容是:文字聊天(包含语音秒数) if ("android.widget.TextView".equals(nodeChild.getClassName()) && "android.widget.RelativeLayout".equals(nodeChild.getParent().getClassName().toString())) { if (!TextUtils.isEmpty(nodeChild.getText())) { String RecordText = nodeChild.getText().toString(); //这里加个if是为了防止多次触发TYPE_VIEW_SCROLLED而打印重复的信息 if (!RecordText.equals(ChatRecord)) { ChatRecord = RecordText; //判断是语音秒数还是正常的文字聊天,语音的话秒数格式为5" if (ChatRecord.contains("\"")) { Toast.makeText(this, ChatName "发了一条" ChatRecord "的语音", Toast.LENGTH_SHORT).show(); Log.e("WeChatLog",ChatName "发了一条" ChatRecord "的语音"); } else { //这里在加多一层过滤条件,确保得到的是聊天信息,因为有可能是其他TextView的干扰,例如名片等 if (nodeChild.isLongClickable()) { Toast.makeText(this, ChatName ":" ChatRecord, Toast.LENGTH_SHORT).show(); Log.e("WeChatLog",ChatName ":" ChatRecord); } } return; } } } //聊天内容是:表情 if ("android.widget.ImageView".equals(nodeChild.getClassName()) && "android.widget.LinearLayout".equals(nodeChild.getParent().getClassName().toString())) { Toast.makeText(this, ChatName "发的是表情", Toast.LENGTH_SHORT).show(); Log.e("WeChatLog",ChatName "发的是表情"); return; } //聊天内容是:图片 if ("android.widget.ImageView".equals(nodeChild.getClassName())) { //安装软件的这一方发的图片(另一方发的暂时没实现) if("android.widget.FrameLayout".equals(nodeChild.getParent().getClassName().toString())){ if(!TextUtils.isEmpty(nodeChild.getContentDescription())){ if(nodeChild.getContentDescription().toString().contains("图片")){ Toast.makeText(this, ChatName "发的是图片", Toast.LENGTH_SHORT).show(); Log.e("WeChatLog",ChatName "发的是图片"); } } } } //聊天内容是:小视频秒数,格式为00:00 if ("android.widget.TextView".equals(nodeChild.getClassName()) && "android.widget.FrameLayout".equals(nodeChild.getParent().getClassName().toString())) { if (!TextUtils.isEmpty(nodeChild.getText())) { String second = nodeChild.getText().toString().replace(":", ""); //正则表达式,确定是不是纯数字,并且做重复判断 if (second.matches("[0-9] ") && !second.equals(VideoSecond)) { VideoSecond = second; Toast.makeText(this, ChatName "发了一段" nodeChild.getText().toString() "的小视频", Toast.LENGTH_SHORT).show(); Log.e("WeChatLog","发了一段" nodeChild.getText().toString() "的小视频"); } } } GetChatRecord(nodeChild); } } /** * 必须重写的方法:系统要中断此service返回的响应时会调用。在整个生命周期会被调用多次。 */ @Override public void onInterrupt() { Toast.makeText(this, "我快被终结了啊-----", Toast.LENGTH_SHORT).show(); } /** * 服务开始连接 */ @Override protected void onServiceConnected() { Toast.makeText(this, "服务已开启", Toast.LENGTH_SHORT).show(); super.onServiceConnected(); } /** * 服务断开 * * @param intent * @return */ @Override public boolean onUnbind(Intent intent) { Toast.makeText(this, "服务已被关闭", Toast.LENGTH_SHORT).show(); return super.onUnbind(intent); }
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论