找传奇、传世资源到传世资源站!

android 读取微信聊天内容 示例源码(AccessibilityService...

8.5玩家评分(1人评分)
下载后可评
介绍 评论 失效链接反馈

微信聊天界面的布局,查看方法: AndroidStudio--Tools--Android--Android Device Monitor
from clipboard 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); }

评论

发表评论必须先登陆, 您可以 登陆 或者 注册新账号 !


在线咨询: 问题反馈
客服QQ:174666394

有问题请留言,看到后及时答复