一、什么是AccessibilityService?

AccessibilityService是android的一个辅助服务抽象类,它是继承Service类,可以用于监听通知栏的变化、窗体改变、窗体内容改变、EditText光标移动、TextView内容改变等事件。


二、基本实现流程。

如下图:



三、主要代码段。

1、RedPacket类继承AccessibilityService,实现如下:

package com.nicksong.luckymoney;import java.io.IOException;import java.util.List;import android.accessibilityservice.AccessibilityService;import android.annotation.SuppressLint;import android.app.Notification;import android.app.PendingIntent;import android.app.PendingIntent.CanceledException;import android.content.res.AssetFileDescriptor;import android.content.res.AssetManager;import android.media.MediaPlayer;import android.util.Log;import android.view.accessibility.AccessibilityEvent;import android.view.accessibility.AccessibilityNodeInfo;public class RedPacket extends AccessibilityService {private MediaPlayer player;private boolean isFirst = false;@Overridepublic void onAccessibilityEvent(AccessibilityEvent event) {int eventType = event.getEventType();switch (eventType) {//第一步:监听通知栏消息case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:List texts = event.getText();if (!texts.isEmpty()) {for (CharSequence text : texts) {String content = text.toString();Log.i("demo", "text:"+content);if (content.contains("[微信红包]")) {isFirst = true;playSound4LuckyMoneyComing();//模拟打开通知栏消息if (event.getParcelableData() != null && event.getParcelableData() instanceof Notification) {Notification notification = (Notification) event.getParcelableData();PendingIntent pendingIntent = notification.contentIntent;try {pendingIntent.send();} catch (CanceledException e) {e.printStackTrace();}}}}}break;//第二步:监听是否进入微信红包消息界面case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:String className = event.getClassName().toString();if (className.equals("com.tencent.mm.ui.LauncherUI")) {Log.i("demo", "开始抢红包");//开始抢红包getPacket();} else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI")) {Log.i("demo", "开始拆红包");isFirst = false;//开始打开红包openPacket();}//else if (className.equals("com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI")) {//Log.i("demo", "在红包详情直接返回");////模拟点击返回//goBackFromLmUi();//}break;}}/** * 在红包详情界面模拟返回 */private void goBackFromLmUi() {isFirst = false;AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();if (nodeInfo != null) {for (int i = 0; i < nodeInfo.getChildCount(); i++) {Log.i("demo", "goBackFromLmUi i = " + i);Log.i("demo", "goBackFromLmUi Click"+",isClickable:" + nodeInfo.getChild(i).isClickable());Log.i("demo", "goBackFromLmUi View type = " + nodeInfo.getChild(i).getClassName());if ("android.widget.LinearLayout".equals(nodeInfo.getChild(i).getClassName()) && nodeInfo.getChild(i).isClickable()) {nodeInfo.getChild(i).performAction(AccessibilityNodeInfo.ACTION_CLICK);}}}}/** * 查找到 */@SuppressLint("NewApi")private void openPacket() {AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();if (nodeInfo != null) {for (int i = 0; i < nodeInfo.getChildCount(); i++) {Log.i("demo", "openPacket i = " + i);Log.i("demo", "Click"+",isClickable:" + nodeInfo.getChild(i).isClickable());Log.i("demo", "View type = " + nodeInfo.getChild(i).getClassName());if ("android.widget.Button".equals(nodeInfo.getChild(i).getClassName()) && nodeInfo.getChild(i).isClickable()) {nodeInfo.getChild(i).performAction(AccessibilityNodeInfo.ACTION_CLICK);}}}}@SuppressLint("NewApi")private void getPacket() {AccessibilityNodeInfo rootNode = getRootInActiveWindow();recycle(rootNode);}/** * 打印一个节点的结构 * @param info */@SuppressLint("NewApi")public void recycle(AccessibilityNodeInfo info) {        if (info.getChildCount() == 0) {         if(info.getText() != null){        if("领取红包".equals(info.getText().toString())){        //这里有一个问题需要注意,就是需要找到一个可以点击的View                Log.i("demo", "Click"+",isClick:"+info.isClickable());                info.performAction(AccessibilityNodeInfo.ACTION_CLICK);                AccessibilityNodeInfo parent = info.getParent();                while(parent != null){                Log.i("demo", "parent isClick:"+parent.isClickable());                if(parent.isClickable() && isFirst){                 parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);                break;                }                parent = parent.getParent();                }                            }        }                } else {              for (int i = 0; i < info.getChildCount(); i++) {                  if(info.getChild(i)!=null){                      recycle(info.getChild(i));                }              }          }      }  @Overridepublic void onInterrupt() {}private void playSound4LuckyMoneyComing() {try {AssetManager assetManager = this.getAssets();AssetFileDescriptor aFileDescriptor = assetManager.openFd("luckymoney_sound.ogg");player = new MediaPlayer();player.setDataSource(aFileDescriptor.getFileDescriptor(), aFileDescriptor.getStartOffset(), aFileDescriptor.getLength());player.prepare();player.start();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

2、res/xml/accessibility.xml如下:

<?xml version="1.0" encoding="utf-8"?>


3、manifest清单文件主要部分如下:

                                                    


四、“设置-辅助服务”打开“微信红包插件”服务。

不同的手机,这个辅助服务的名称、位置可能都不一样,这个就要大家在自己手机里找一下,应该很快能找到。如,魅族的一款手机,这个菜单位置如下截图:

   

五、源码。

https://github.com/Ericsongyl/WechatRedPacket

欢迎star、fork,并提出宝贵意见和建议。

注意:Android系统4.1以上、微信版本6.3.28及以上。


---------------------------------------------------------------------------------------------------------------

声明:请勿商用,否则后果由投入商用者本人承担!

更多相关文章

  1. tcping测试服务器TCP端口
  2. 使用AIDL实现进程间的通信
  3. 浅析Android(安卓)Service 中 onStartCommand方法及注意事项
  4. android如何得到控件大小 OnGlobalLayoutListener
  5. Android(安卓)Socket服务器 Servlet服务器
  6. smack 源码分析- PacketReader (android上实现长连接)【3】
  7. 【Android】BroadcastReceiver发送intent给service或者activity
  8. Android笔记——如何将软键盘的回车键改为搜索键
  9. Android(安卓)实现“再按一次退出程序”

随机推荐

  1. Android(安卓)- 获取版本号、判断当前是
  2. RK3288_Android7.1接eDP屏休眠之后led状
  3. Android(安卓)Fragment onActivityResult
  4. 你了解Android中的Activity吗?
  5. 直播源码Android(安卓)屏幕常亮N秒后自动
  6. android 8.1 下拉栏Systemui的修改
  7. Android(安卓)Test(未完工)
  8. Android初级教程_获取Android控件的宽和
  9. cordova+vue构建iOS APP
  10. GPS定位及获取卫星参数实例整理