实例介绍
微信聊天界面的布局,查看方法:
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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论