Android:辅助功能之自动抢红包

hi大家好。
新年又来了,微信群里又是各种红包横飞。作为技术人员的我们却大可不必担心一不小心,手速慢了点,又错过了几十万。我们可以通过安卓的辅助功能来实现自己的微信自动抢红包,安全又快捷。

辅助服务

我们在 设置->无障碍 中,就可以看到手机中所有的辅助服务了。辅助功能通常是针对一些视力听力等有障碍导致使用手机有障碍的人群,做一些语言提醒等帮助他们更好地使用手机。
因为辅助功能可以得到系统级别的事件和服务,第三方应用的辅助功能都需要手动开启。我们常用的绿色守护,冰箱等应用都是利用辅助服务实现的。

image

我们先来实现一个简单的辅助服务吧。

1,继承AccessibilityService类。AccessibilityService类一共有四个可以重写的方法。

TestService类

public class TestService extends AccessibilityService {
    /**
     *  必须重写的方法:此方法用了接受系统发来的event。在你注册的event发生是被调用。在整个生命周期会被调用多次。
     */
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }

   /**
     *  必须重写的方法:系统要中断此service返回的响应时会调用。在整个生命周期会被调用多次。
     */
    @Override
    public void onInterrupt() {
    }

     /**
     *  当系统连接上你的服务时被调用
     */
    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
    }


    /**
     *  在系统要关闭此service时调用。
     */
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
}

2,给你的辅助服务写一个配置文件。
res/xml/text_server_config.xml

<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_description"
    android:notificationTimeout="10" />

看属性的名字应该比较容易猜测到不同是属性是用来干嘛的。

accessibilityEventTypes:响应那种类型的事件

accessibilityFeedbackType:用什么方式反馈给用户

notificationTimeout:响应时间

packageNames:指定响应哪个应用的事件。如果不填则是响应所有的应用事件(如果以后写抢红包的辅助功能,可以只写微信的包名)

description:辅助服务的描述信息。

3,在manifest中注册服务。

        <service
            android:name=".TestService"
            //辅助功能的名称
            android:label="@string/test_service_label"
            //此处必须声明一次权限
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
            //对,我就是上面写好的配置文件
                android:name="android.accessibilityservice"
                android:resource="@xml/text_service_config" />
        </service>

4,最后,回到服务的类,TestService。在onAccessibilityEvent(AccessibilityEvent event)方法中,我们可以接收到系统发过来的事件。当然取决于我们在配置文件中选择了我们要监听哪些种类,哪些应用的事件了。

 public void onAccessibilityEvent(AccessibilityEvent event) {
    //得到事件的包名。如果注册了多个应用的事件,可以在此做一个判断。
    String packageName = event.getPackageName().toString();
    
    //得到对应的事件类型,这里有很多很多种的事件类型,具体可以自行翻阅AccessibilityEvent类中的定义。
    int eventType = event.getEventType();
    
    //得到根的view节点。可以当做当前acitivity的视图看成是树状结构的(实际上也是~。~),而我们现在就得到了它的根节点。
    AccessibilityNodeInfo root = getRootInActiveWindow();
    
    //我们可以得到此节点的文字
    String rootText = root.getText().toString();
    //得到此节点的class
    String rootClass = root.getClass().toString();
    //得到子节点的和子节点总数
    root.getChild(root.getChildCount()-1);
 }
 

到这里,我们可以通过无数次遍历,找到视图上自己想要的那个控件了。当然,还有更加简单的方法。

    //这两个方法如果找不到的话,都会报错。所以请做好对应的处理。
    root.findAccessibilityNodeInfosByText("根据文本内容查找节点");
    root.findAccessibilityNodeInfosByViewId("根据id查找节点,当然实际上很难知道id是多少~、~");

最后我们可以对控件做一些操作,比如

    //点击操作
    root.performAction(AccessibilityNodeInfo.ACTION_CLICK);

    //滑动操作
    root.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);

好,对于辅助服务的基础知识我们学到这里已经差不多了,如果跟着我写了一个demo的童鞋们,可以运行一下,在设置->无障碍中把自己的辅助功能打开试试。把玩一下。


下面可以进入抢红包的开发。

抢红包

我们先回顾一下手动抢红包的过程。
假设小新某天在用手机刷微博。叮叮,听到提示声,通知栏上显示:“小明\n [微信红包]恭喜发财,大吉大利”。
小新光速点了一下微信通知,手机自动跳转到了对应的微信聊天页面,聊天界面里正是一条橙色底色,配上红包图片的信息:“恭喜发财,大吉大利\n领取红包\n微信红包”。
脑子还没反应过来,手指已经自动点到这条信息上,这是有一个正在加载的提示框一闪而过,然后就是正中一个大大的红包,中间是金黄色的“開”字。
不用想了,开!看着开字转啊转,心急如焚。最后屏幕一闪,跳到了红包详情页面,心头大石落地,详情页面写在“0.01分钱”。小新也心满意足地回去看微博了。

我们的自动抢红包就是要自动帮我们完成这么一个流程:
1,获取通知栏的信息,判断是否红包。
2,如果屏幕关着的,先打开屏幕。
3,点击通知,进入聊天界面
4,点击红包信息
5,点击红包中的“開”
6,返回主界面,安安静静了无痕迹。

先上github的地址我是地址;大家可以直接去看代码。代码很简单。无非就是遍历找控件。

1, 得到通知栏信息
通知栏事件

AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED

可以通过event.getText()方法得到通知栏的文字。然后在与“[微信红包]”做对比,判断是否微信红包。

2,
打开屏幕。如果是有屏幕锁的那我就没办法了哎,,知道的童鞋请赐教。

  /**
     * 解锁
     */
    private void wakeAndUnlock() {
        //获取电源管理器对象
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);

        //获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是调试用的Tag
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");

        //点亮屏幕
        wl.acquire(1000);

        //得到键盘锁管理器对象
        KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        kl = km.newKeyguardLock("unLock");

        //解锁
        kl.disableKeyguard();
    }

记得释放键盘管理器

 kl.reenableKeyguard();

3,通过通知栏进入微信聊天界面。

//打开微信聊天页面
    private void openWeichaPage(AccessibilityEvent event) {
        if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {
            //得到通知的对象
            Notification notification = (Notification) event.getParcelableData();

            //得到通知栏的信息
//            String content = notification.tickerText.toString();
//            String name = content.substring(0, content.indexOf(":"));
//            String scontent = content.substring(content.indexOf(":"), content.length());
//            Log.d("mylog", "------openWeichaPage  name: " + name + " content: " + scontent);


            //打开通知栏的intent,即打开对应的聊天界面
            PendingIntent pendingIntent = notification.contentIntent;
            try {
                pendingIntent.send();
            } catch (PendingIntent.CanceledException e) {
                e.printStackTrace();
            }
        }
    }

4,我们需要监听页面的变化加自己定义变量来判断是否跳转到了微信聊天页面。

页面跳转的事件是:

 AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED

微信聊天页面的classname:

com.tencent.mm.ui.LauncherUI

判断的方法:

    String className = event.getClassName().toString();
    
    //是否微信聊天页面的类
    if (className.equals(LAUCHER)) {
       findStuff();
    }

然后就是做遍历,大体思路是调用getChild(i)找到聊天页面中的红包。可以先通过getClassName()比较是否“android.widget.TextView”,然后通过getText()匹配文本内容。

具体方法不表。大家可以自己写写,不想写可以看GitHub上我写的代码。

5,和上面的方法一直,判断窗口跳转,加遍历找到“開”字,对,开 也是一个TextView。

6,至此就大功告成,可以返回桌面了。

 /**
     * 回到系统桌面
     */
    private void back2Home() {
        Intent home = new Intent(Intent.ACTION_MAIN);

        home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        home.addCategory(Intent.CATEGORY_HOME);

        startActivity(home);
    }

我们的抢红包之旅到这里就告一段落了,结束的是一次艰苦的撸代码的时光,开启的是千千万万次自动抢红包的快感。

最后,祝大家新年 大 吉 吧!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,932评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,554评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,894评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,442评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,347评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,899评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,325评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,980评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,196评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,163评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,085评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,826评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,389评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,501评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,753评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,171评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,616评论 2 339

推荐阅读更多精彩内容