用这个工具,发朋友圈都可以自动了

今天推荐是一个比较骚气的工具,自动发朋友圈(不用root手机),对于一天发10多条,甚至20条朋友圈的朋友,每次编辑比较麻烦。我之前也写过抢红包工具,当时上架应用市场时,又恰逢过年,那下载量,比我吃了一桶老坛酸菜面还爽。后来由于应用市场的限制,就下架了,后来反正也不是很么高超的技术,就开源在我的github上了,今天分享这个自动发朋友圈的工具,也是和抢红包原理类似。通过开启辅助工具。进行监控屏幕上的按钮。延伸想想,那些喜欢点赞的朋友,是不是可以稍微改下,就变成了自动打开朋友圈,挨个朋友点赞。想想有木有很激动。哈哈~话不多说,我们进入司徒文德分享的文章。原文链接:https://www.jianshu.com/p/8b4ea121d188

一、效果图

二、测试Android设备 我在这两款设备测试正常,其它设备如果有什么问题,欢迎给我反馈_ 夜神模拟器(Android 4.3)、华为荣耀8青春版(Android 7.0)

三、原理

整个app的核心是AccessibilitySampleService类,它继承了AccessibilityService服务。在辅助功能打开之后,AccessibilitySampleService类会监听目标APP(微信)页面的状态变化。之后使用Android官方提供的UI Automator Viewer工具,查看目标APP(微信)的布局结构树。

根据rescoure-id搜索出相应的控件,再对这些控件执行点击、复制、粘贴等操作。

看下核心实现逻辑

@TargetApi(18)
public class AccessibilitySampleService extends AccessibilityService {
    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        flag = false;
    }
    private AccessibilityNodeInfo accessibilityNodeInfo;
    /**
     * 是否已经发送过朋友圈,true已经发送,false还未发送
     */
    public static boolean flag = false;
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        SharedPreferences sharedPreferences = getSharedPreferences(Constant.WECHAT_STORAGE, Activity.MODE_PRIVATE);
        int eventType = event.getEventType();
        LogUtil.e(eventType + "             " + Integer.toHexString(eventType) + "         " + event.getClassName());
        accessibilityNodeInfo = getRootInActiveWindow();
        if (accessibilityNodeInfo == null) {
            return;
        }
        switch (eventType) {
            case AccessibilityEvent.TYPE_VIEW_SCROLLED:
                if (!flag && event.getClassName().equals("android.widget.ListView")) {
                    clickCircleOfFriendsBtn();//点击发送朋友圈按钮
                }
                break;
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                if (event.getClassName().equals("com.tencent.mm.ui.LauncherUI")) {//第一次启动app
                    flag = false;
                    jumpToCircleOfFriends();//进入朋友圈页面
                }
                if (!flag && event.getClassName().equals("com.tencent.mm.plugin.sns.ui.SnsUploadUI")) {
                    String content = sharedPreferences.getString(Constant.CONTENT, "");
                    inputContentFinish(content);//写入要发送的朋友圈内容
                }
                break;
        }
    }
    /**
     * 跳进朋友圈
     */
    private void jumpToCircleOfFriends() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                List<AccessibilityNodeInfo> accessibilityNodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId("android:id/list");
                if (accessibilityNodeInfoList != null && accessibilityNodeInfoList.size() != 0) {
                    AccessibilityNodeInfo accessibilityNodeInfo = accessibilityNodeInfoList.get(0);
                    if (accessibilityNodeInfo != null) {
                        accessibilityNodeInfo = accessibilityNodeInfo.getChild(1);
                        if (accessibilityNodeInfo != null) {
                            accessibilityNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                        }
                    }
                }
            }
        }, 1500);
    }
    /**
     * 写入朋友圈内容
     *
     * @param contentStr
     */
    private void inputContentFinish(final String contentStr) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                List<AccessibilityNodeInfo> accessibilityNodeInfoList1 = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/dba");
                if (accessibilityNodeInfoList1.size() > 0) {
                    ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
                    ClipData clip = ClipData.newPlainText("text", contentStr);
                    if (clipboard == null) {
                        return;
                    }
                    clipboard.setPrimaryClip(clip);
                    accessibilityNodeInfoList1.get(0).performAction(AccessibilityNodeInfo.ACTION_FOCUS);
                    accessibilityNodeInfoList1.get(0).performAction(AccessibilityNodeInfo.ACTION_PASTE);
                    LogUtil.e("写入内容");
                }
                List<AccessibilityNodeInfo> accessibilityNodeInfoList =
                        accessibilityNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/h5");//点击发送
                if (accessibilityNodeInfoList == null || accessibilityNodeInfoList.size() == 0) {
                    LogUtil.e("发送朋友圈失败");
                    return;
                }
                accessibilityNodeInfoList.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
                Toast.makeText(getApplicationContext(), "发送朋友圈成功", Toast.LENGTH_LONG).show();
                flag = true;//标记为已发送
            }
        }, 1500);
    }
    /**
     * 选择图片
     *
     * @param startPicIndex 从第startPicIndex张开始选
     * @param picCount      总共选picCount张
     */
    private void choosePicture(final int startPicIndex, final int picCount) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                List<AccessibilityNodeInfo> accessibilityNodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/cyh");
                for (int i = 0; i < accessibilityNodeInfoList.size(); i++) {
                    for (int j = startPicIndex; j < startPicIndex + picCount; j++) {
                        AccessibilityNodeInfo childNodeInfo = accessibilityNodeInfoList.get(i).getChild(j);
                        if (childNodeInfo != null) {
                            List<AccessibilityNodeInfo> childNodeInfoList = childNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/bnl");
                            if (childNodeInfoList != null && childNodeInfoList.size() != 0) {
                                childNodeInfoList.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            }
                        }
                    }
                }
                List<AccessibilityNodeInfo> finishList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/h5");//点击确定
                if (finishList != null && finishList.size() != 0) {
                    finishList.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    LogUtil.e("完成图片选择!");
                }
            }
        }, 1500);
    }
    /**
     * 点击发送朋友圈按钮
     */
    private void clickCircleOfFriendsBtn() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (accessibilityNodeInfo == null) {
                    return;
                }
                List<AccessibilityNodeInfo> accessibilityNodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/g1");
                if (accessibilityNodeInfoList != null && accessibilityNodeInfoList.size() != 0 &&
                        accessibilityNodeInfoList.get(0) != null && accessibilityNodeInfoList.get(0).getParent() != null) {
                    accessibilityNodeInfoList.get(0).getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
                openAlbum();
            }
        }, 1500);
    }
    /**
     * 打开相册
     */
    private void openAlbum() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (accessibilityNodeInfo == null) {
                    return;
                }
                List<AccessibilityNodeInfo> accessibilityNodeInfoList = accessibilityNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/axk");
                if (accessibilityNodeInfoList != null && accessibilityNodeInfoList.size() != 0 && accessibilityNodeInfoList.get(0).getChildCount() != 0) {
                    accessibilityNodeInfoList.get(0).getChild(1).performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    LogUtil.e("打开相册!");
                    SharedPreferences sharedPreferences = getSharedPreferences(Constant.WECHAT_STORAGE, Activity.MODE_PRIVATE);
                    if (sharedPreferences != null) {
                        int index = sharedPreferences.getInt(Constant.INDEX, 0);
                        int count = sharedPreferences.getInt(Constant.COUNT, 0);
                        choosePicture(index, count);
                    }
                }
            }
        }, 1500);
    }
    @Override
    public void onInterrupt() {
    }
    /**
     * Called by the system to notify a Service that it is no longer used and is being removed.  The
     * service should clean up any resources it holds (threads, registered
     * receivers, etc) at this point.  Upon return, there will be no more calls
     * in to this Service object and it is effectively dead.  Do not call this method directly.
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        LogUtil.e("服务被杀死!");
    }
}

四、注意事项 1、Android设备必须安装微信app 2、Android Sdk Version>18 特别提醒(不需要获取root权限)

原文发布于微信公众号 - 何俊林(DriodDeveloper)

原文发表时间:2018-04-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android-薛之涛

ViewFlipper-仿淘宝垂直广告滚动

viewflipper的子布局item_viewflipper.xml,下面是效果图,自己写,不会没招。

9722
来自专栏小灰灰

Spring之动态注册bean

如我之前做个的一个支持扫表的基础平台,使用者只需要添加基础配置 + Groovy任务,就可以丢到这个平台上面来运行了,而这个基础平台是一直都在运行的,所以在新来...

1673
来自专栏GIS讲堂

Arcgis andoid开发之应用百度地图接口实现精准定位与显示

怀着激动、兴奋的心情,在这个漫天柳絮的季节写下了这片博文,为什么呢,因为困扰我很久的一个技术性的问题得到了解决,发次博文,供大家参观、学习,同时,也以慰藉我长期...

1333
来自专栏向治洪

Android开发模式之MVC,MVP和MVVM的简单介绍与区别

相信大家对MVC,MVP和MVVM都不陌生,作为三个最耳熟能详的Android框架,它们的应用可以是非常广泛的,但是对于一些新手来说,可能对于区分它们三个都有困...

1.3K8
来自专栏刘望舒

感受LiveData与ViewModel结合之美

虽说这篇是说LiveData与ViewModel,但是或多或少都有涉及另外一个组件:Lifecycles 。它们连同Room都是在17年谷歌IO大会推出的,当时...

1412
来自专栏曾大稳的博客

OpenGLES渲染画面通过MediaCodec录制

通过fbo处理视频数据,通过samplerExternalOES纹理来创建SurfaceTexture,这样的话摄像头数据就和fbo相关联,具体可以看OpenG...

3304
来自专栏增长技术

Android 相机功能模块相关库

Android’s video recording APIs are very difficult to figure out, especially sinc...

2171
来自专栏青蛙要fly的专栏

Android技能树 — View事件体系小结

这次是讲View的事件体系。特别是不同情况下的事件分发,我会用很简单的方式教会大家。

1211
来自专栏项勇

笔记19 | 利用MediaRecorder实现录像

24410
来自专栏向治洪

讯飞语音

、你需要android手机应用开发基础 2、科大讯飞语音识别SDK android版 3、科大讯飞语音识别开发API文档 4、android手机 关于科大讯飞S...

31810

扫码关注云+社区

领取腾讯云代金券