首页

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

java

2020-7-9

微信聊天界面的布局,查看方法:

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);
    }

资源下载此资源下载价格为33D币(VIP免费),请先
资源文件列表
.gradle/3.3/taskArtifacts/fileHashes.bin , 161033
.gradle/3.3/taskArtifacts/fileSnapshots.bin , 662574
.gradle/3.3/taskArtifacts/taskArtifacts.bin , 46740
.gradle/3.3/taskArtifacts/taskArtifacts.lock , 17
.gradle/3.3/tasks/_app_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin , 21968
.gradle/3.3/tasks/_app_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock , 17
.gradle/3.3/tasks/_app_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin , 19810
.gradle/3.3/tasks/_app_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock , 17
.idea/compiler.xml , 686
.idea/copyright/profiles_settings.xml , 74
.idea/gradle.xml , 626
.idea/libraries/animated_vector_drawable_25_3_1.xml , 607
.idea/libraries/appcompat_v7_25_3_1.xml , 571
.idea/libraries/espresso_core_2_2_2.xml , 585
.idea/libraries/espresso_idling_resource_2_2_2.xml , 618
.idea/libraries/exposed_instrumentation_api_publish_0_5.xml , 636
.idea/libraries/hamcrest_core_1_3.xml , 526
.idea/libraries/hamcrest_integration_1_3.xml , 354
.idea/libraries/hamcrest_library_1_3.xml , 342
.idea/libraries/javawriter_2_1_1.xml , 330
.idea/libraries/javax_annotation_api_1_2.xml , 358
.idea/libraries/javax_inject_1.xml , 324
.idea/libraries/jsr305_2_0_1.xml , 330
.idea/libraries/junit_4_12.xml , 477
.idea/libraries/rules_0_5.xml , 546
.idea/libraries/runner_0_5.xml , 549
.idea/libraries/support_annotations_25_3_1.xml , 507
.idea/libraries/support_compat_25_3_1.xml , 577
.idea/libraries/support_core_ui_25_3_1.xml , 580
.idea/libraries/support_core_utils_25_3_1.xml , 589
.idea/libraries/support_fragment_25_3_1.xml , 583
.idea/libraries/support_media_compat_25_3_1.xml , 595
.idea/libraries/support_v4_25_3_1.xml , 404
.idea/libraries/support_vector_drawable_25_3_1.xml , 604
.idea/misc.xml , 2644
.idea/modules.xml , 553
.idea/runConfigurations.xml , 564
.idea/workspace.xml , 153420
app/.gitignore , 7
app/app.iml , 9984
app/build.gradle , 866
app/build/generated/source/buildConfig/androidTest/debug/com/cxk/wechatlog/test/BuildConfig.java , 451
app/build/generated/source/buildConfig/debug/com/cxk/wechatlog/BuildConfig.java , 441
app/build/generated/source/r/androidTest/debug/android/app/R.java , 241
app/build/generated/source/r/androidTest/debug/android/support/test/espresso/idling/R.java , 266
app/build/generated/source/r/androidTest/debug/android/support/test/espresso/R.java , 362
app/build/generated/source/r/androidTest/debug/android/support/test/R.java , 250
app/build/generated/source/r/androidTest/debug/android/support/test/rule/R.java , 358
app/build/generated/source/r/androidTest/debug/com/cxk/wechatlog/test/R.java , 397
app/build/generated/source/r/debug/android/support/compat/R.java , 252
app/build/generated/source/r/debug/android/support/coreui/R.java , 252
app/build/generated/source/r/debug/android/support/coreutils/R.java , 255
app/build/generated/source/r/debug/android/support/fragment/R.java , 254
app/build/generated/source/r/debug/android/support/graphics/drawable/animated/R.java , 272
app/build/generated/source/r/debug/android/support/graphics/drawable/R.java , 263
app/build/generated/source/r/debug/android/support/mediacompat/R.java , 257
app/build/generated/source/r/debug/android/support/v4/R.java , 248
app/build/generated/source/r/debug/android/support/v7/appcompat/R.java , 110550
app/build/generated/source/r/debug/com/cxk/wechatlog/R.java , 428047
app/build/intermediates/blame/res/androidTest/debug/multi/values.json , 928
app/build/intermediates/blame/res/debug/multi/values-af.json , 15587
app/build/intermediates/blame/res/debug/multi/values-am.json , 15581
app/build/intermediates/blame/res/debug/multi/values-ar.json , 15589
app/build/intermediates/blame/res/debug/multi/values-az-rAZ.json , 15019
app/build/intermediates/blame/res/debug/multi/values-b+sr+Latn.json , 15899
app/build/intermediates/blame/res/debug/multi/values-be-rBY.json , 15769
app/build/intermediates/blame/res/debug/multi/values-bg.json , 15593
app/build/intermediates/blame/res/debug/multi/values-bn-rBD.json , 15773
app/build/intermediates/blame/res/debug/multi/values-bs-rBA.json , 15769
app/build/intermediates/blame/res/debug/multi/values-ca.json , 15593
app/build/intermediates/blame/res/debug/multi/values-cs.json , 15589
app/build/intermediates/blame/res/debug/multi/values-da.json , 15585
app/build/intermediates/blame/res/debug/multi/values-de.json , 15589
app/build/intermediates/blame/res/debug/multi/values-el.json , 15595
app/build/intermediates/blame/res/debug/multi/values-en-rAU.json , 15761
app/build/intermediates/blame/res/debug/multi/values-en-rGB.json , 15761
app/build/intermediates/blame/res/debug/multi/values-en-rIN.json , 15761
app/build/intermediates/blame/res/debug/multi/values-es-rUS.json , 15771
app/build/intermediates/blame/res/debug/multi/values-es.json , 15591
app/build/intermediates/blame/res/debug/multi/values-et-rEE.json , 15771
app/build/intermediates/blame/res/debug/multi/values-eu-rES.json , 15767
app/build/intermediates/blame/res/debug/multi/values-fa.json , 15591
app/build/intermediates/blame/res/debug/multi/values-fi.json , 15585
app/build/intermediates/blame/res/debug/multi/values-fr-rCA.json , 15771
app/build/intermediates/blame/res/debug/multi/values-fr.json , 15595
app/build/intermediates/blame/res/debug/multi/values-gl-rES.json , 15769
app/build/intermediates/blame/res/debug/multi/values-gu-rIN.json , 15765
app/build/intermediates/blame/res/debug/multi/values-h320dp-v13.json , 961
app/build/intermediates/blame/res/debug/multi/values-h720dp-v13.json , 961
app/build/intermediates/blame/res/debug/multi/values-hdpi-v4.json , 1021
app/build/intermediates/blame/res/debug/multi/values-hi.json , 15591
app/build/intermediates/blame/res/debug/multi/values-hr.json , 15589
app/build/intermediates/blame/res/debug/multi/values-hu.json , 15595
app/build/intermediates/blame/res/debug/multi/values-hy-rAM.json , 15763
app/build/intermediates/blame/res/debug/multi/values-in.json , 15591
app/build/intermediates/blame/res/debug/multi/values-is-rIS.json , 15759
app/build/intermediates/blame/res/debug/multi/values-it.json , 15587
app/build/intermediates/blame/res/debug/multi/values-iw.json , 15583
app/build/intermediates/blame/res/debug/multi/values-ja.json , 15577
app/build/intermediates/blame/res/debug/multi/values-ka-rGE.json , 15767
app/build/intermediates/blame/res/debug/multi/values-kk-rKZ.json , 15765
app/build/intermediates/blame/res/debug/multi/values-km-rKH.json , 15763
app/build/intermediates/blame/res/debug/multi/values-kn-rIN.json , 15769
app/build/intermediates/blame/res/debug/multi/values-ko.json , 15573
app/build/intermediates/blame/res/debug/multi/values-ky-rKG.json , 15765
app/build/intermediates/blame/res/debug/multi/values-land.json , 3133
app/build/intermediates/blame/res/debug/multi/values-large-v4.json , 6879
app/build/intermediates/blame/res/debug/multi/values-ldltr-v21.json , 959
app/build/intermediates/blame/res/debug/multi/values-lo-rLA.json , 15761
app/build/intermediates/blame/res/debug/multi/values-lt.json , 15595
app/build/intermediates/blame/res/debug/multi/values-lv.json , 15593
app/build/intermediates/blame/res/debug/multi/values-mk-rMK.json , 14279
app/build/intermediates/blame/res/debug/multi/values-ml-rIN.json , 15769
app/build/intermediates/blame/res/debug/multi/values-mn-rMN.json , 15763
app/build/intermediates/blame/res/debug/multi/values-mr-rIN.json , 15769
app/build/intermediates/blame/res/debug/multi/values-ms-rMY.json , 15767
app/build/intermediates/blame/res/debug/multi/values-my-rMM.json , 15771
app/build/intermediates/blame/res/debug/multi/values-nb.json , 15581
app/build/intermediates/blame/res/debug/multi/values-ne-rNP.json , 15773
app/build/intermediates/blame/res/debug/multi/values-night-v8.json , 5397
app/build/intermediates/blame/res/debug/multi/values-nl.json , 15595
app/build/intermediates/blame/res/debug/multi/values-pa-rIN.json , 15761
app/build/intermediates/blame/res/debug/multi/values-pl.json , 15591
app/build/intermediates/blame/res/debug/multi/values-port.json , 937
app/build/intermediates/blame/res/debug/multi/values-pt-rBR.json , 15771
app/build/intermediates/blame/res/debug/multi/values-pt-rPT.json , 15771
app/build/intermediates/blame/res/debug/multi/values-pt.json , 15595
app/build/intermediates/blame/res/debug/multi/values-ro.json , 15595
app/build/intermediates/blame/res/debug/multi/values-ru.json , 15593
app/build/intermediates/blame/res/debug/multi/values-si-rLK.json , 15767
app/build/intermediates/blame/res/debug/multi/values-sk.json , 15587
app/build/intermediates/blame/res/debug/multi/values-sl.json , 15591
app/build/intermediates/blame/res/debug/multi/values-sq-rAL.json , 15767
app/build/intermediates/blame/res/debug/multi/values-sr.json , 15591
app/build/intermediates/blame/res/debug/multi/values-sv.json , 15589
app/build/intermediates/blame/res/debug/multi/values-sw.json , 15587
app/build/intermediates/blame/res/debug/multi/values-sw600dp-v13.json , 6187
app/build/intermediates/blame/res/debug/multi/values-ta-rIN.json , 15769
app/build/intermediates/blame/res/debug/multi/values-te-rIN.json , 15771
app/build/intermediates/blame/res/debug/multi/values-th.json , 15587
app/build/intermediates/blame/res/debug/multi/values-tl.json , 15597
app/build/intermediates/blame/res/debug/multi/values-tr.json , 15587
app/build/intermediates/blame/res/debug/multi/values-uk.json , 15589
app/build/intermediates/blame/res/debug/multi/values-ur-rPK.json , 15765
app/build/intermediates/blame/res/debug/multi/values-uz-rUZ.json , 15769
app/build/intermediates/blame/res/debug/multi/values-v11.json , 19201
app/build/intermediates/blame/res/debug/multi/values-v12.json , 3269
app/build/intermediates/blame/res/debug/multi/values-v13.json , 933
app/build/intermediates/blame/res/debug/multi/values-v14.json , 9311
app/build/intermediates/blame/res/debug/multi/values-v16.json , 933
app/build/intermediates/blame/res/debug/multi/values-v17.json , 11511
最多只能显示150条信息!
没有账号? 忘记密码?

社交账号快速登录