微信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
正在加载信息~
推荐阅读
站点信息
- 文章2314
- 用户1336
- 访客11813325
每日一句
Let's seek joy in the simple, quiet moments.
让我们在简单宁静的时刻中寻找快乐。
让我们在简单宁静的时刻中寻找快乐。