微信7.0版本之前抢红包插件点击基本上都借助AccessibilityService无障碍的performClick方法点击控件,不过7.0版本的微信的红包控件(view)没有id这一项了,所以performClick就无法使用了,但是抢红包就在此停止了吗?非也,下面给出2种点击方法。
方法一(验证有效)
此方法免root,不过需要Android7.0及以上版本,AccessibilityService有个新的选项,canPerformGestures: 安卓7.0后可通过dispatchGesture实现点击屏幕的操作,如需用此方法需将canPerformGestures设置为true
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:canPerformGestures="true" android:description="@string/accessibility_service_description" /> <!--android:canPerformGestures 是否可以执行手势(api 24新增)-->
模拟点击的方法dispatchGesture
@TargetApi(24) public void click(Point point) { //只有7.0才可以用 GestureDescription.Builder builder = new GestureDescription.Builder(); Path path = new Path(); path.moveTo((float) point.x, (float) point.y); path.lineTo((float) point.x, (float) point.y); /** * 参数path:笔画路径 * 参数startTime:时间 (以毫秒为单位),从手势开始到开始笔划的时间,非负数 * 参数duration:笔划经过路径的持续时间(以毫秒为单位),非负数 */ builder.addStroke(new GestureDescription.StrokeDescription(path, 1, 1)); final GestureDescription build = builder.build(); /** * 参数GestureDescription:翻译过来就是手势的描述,如果要实现模拟,首先要描述你的腰模拟的手势嘛 * 参数GestureResultCallback:翻译过来就是手势的回调,手势模拟执行以后回调结果 * 参数handler:大部分情况我们不用的话传空就可以了 * 一般我们关注GestureDescription这个参数就够了,下边就重点介绍一下这个参数 */ dispatchGesture(build, new GestureResultCallback() { public void onCancelled(GestureDescription gestureDescription) { super.onCancelled(gestureDescription); } public void onCompleted(GestureDescription gestureDescription) { super.onCompleted(gestureDescription); } }, null); }
然后配合MediaProjection录屏进行图片识别即可。
/** * 申请屏幕录取权限 */ private void requestScreenShot() { startActivityForResult( ((MediaProjectionManager) this.getActivity().getSystemService("media_projection")).createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION); } public Bitmap getScreenShotSync() { if (!isShotterUseful()) { return null; } if (mImageReader == null) { mImageReader = ImageReader.newInstance( getScreenWidth(), getScreenHeight(), PixelFormat.RGBA_8888,//此处必须和下面 buffer处理一致的格式 ,RGB_565在一些机器上出现兼容问题。 1); } VirtualDisplay tmpDisplay = virtualDisplay(); try{ Thread.sleep(50); //需要稍微停一下,否则截图为空 }catch (InterruptedException e){ e.printStackTrace(); } Image img = mImageReader.acquireLatestImage(); if (img == null) { return null; } int width = img.getWidth(); int height = img.getHeight(); final Image.Plane[] planes = img.getPlanes(); final ByteBuffer buffer = planes[0].getBuffer(); //每个像素的间距 int pixelStride = planes[0].getPixelStride(); //总的间距 int rowStride = planes[0].getRowStride(); int rowPadding = rowStride - pixelStride * width; Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);//虽然这个色彩比较费内存但是 兼容性更好 bitmap.copyPixelsFromBuffer(buffer); bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height); img.close(); //mImageReader.close(); tmpDisplay.release(); return bitmap; } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private VirtualDisplay virtualDisplay() { return mMediaProjection.createVirtualDisplay("screen-mirror", getScreenWidth(), getScreenHeight(), Resources.getSystem().getDisplayMetrics().densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null); }
抢红包开源地址:https://github.com/LnJan/WechatLuckyMoneyGetter
方法二(未验证)
此方法依然使用的是adb shell,不过并不需要root方法。其中奥秘在于app_process启动一个dex的java程序(shell启动的程序必然有shell权限),利用此程序的shell启动权限进行点击点击,程序的后台卸载、安装都可以。
这个引用一个已经实现的项目
收藏的用户(0) X
正在加载信息~
推荐阅读
站点信息
- 文章2300
- 用户1336
- 访客10722994
每日一句
All things in their being are good for something.
天生我材必有用。
天生我材必有用。
新会员