diff --git a/app/build.gradle b/app/build.gradle index 62c1059..c996440 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -61,5 +61,7 @@ dependencies { //自动更新 implementation 'com.teprinciple:updateapputilsx:2.3.0' //ok - api 'com.lzy.net:okgo:3.0.4' + implementation 'com.lzy.net:okgo:3.0.4' + //qrcode + implementation 'com.github.yoojia:next-qrcode:2.0-2' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 541901c..1774b6a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,7 +27,8 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" - android:usesCleartextTraffic="true"> + android:usesCleartextTraffic="true" + android:requestLegacyExternalStorage="true"> 0) { LogUtils.i("发现未读消息: " + spotNodeList.size + "条") log("发现未读消息: " + spotNodeList.size + "条") - for (spotNode in spotNodeList) { - if (AccessibilityUtil.performClick(spotNode)) { - //进入聊天页 下一步 getChatMessageList - break + if (AccessibilityUtil.performClick(spotNodeList.first())) { + //进入聊天页 下一步 getChatMessageList + } else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + AccessibilityUtil + .clickByNode(WeworkController.weworkService, spotNodeList.first().parent) + } else { + LogUtils.e("请将手机版本提升到 Android 7.0+ 或将企业微信版本回退到 4.0.8之前(4.0.6可用)") } } return true diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt b/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt index 51ab676..f6f391e 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt @@ -1,13 +1,16 @@ package org.yameida.worktool.service import android.view.accessibility.AccessibilityNodeInfo -import com.blankj.utilcode.util.LogUtils import org.yameida.worktool.Constant import org.yameida.worktool.model.WeworkMessageBean import org.yameida.worktool.utils.AccessibilityUtil import org.yameida.worktool.utils.Views import org.yameida.worktool.utils.WeworkRoomUtil import org.yameida.worktool.utils.WeworkTextUtil +import com.github.yoojia.qrcode.qrcode.QRCodeDecoder +import com.blankj.utilcode.util.* +import java.lang.Exception + /** * 全局操作类型 200 实现类 @@ -145,13 +148,76 @@ object WeworkOperationImpl { selectList: List?, groupAnnouncement: String? ): Boolean { - if (!createGroup() || !groupRename(groupName) || !groupAddMember(selectList) - || !groupChangeAnnouncement(groupAnnouncement) - ) return false - backPress() + if (!WeworkRoomUtil.isGroupExists(groupName)) { + if (!createGroup() || !groupRename(groupName) || !groupAddMember(selectList) + || !groupChangeAnnouncement(groupAnnouncement) + ) return false + } else { + if (!groupRename(groupName) || !groupAddMember(selectList) + || !groupChangeAnnouncement(groupAnnouncement) + ) return false + } + getGroupQrcode(groupName) return true } + fun getGroupQrcode(groupName: String): Boolean { + if (WeworkRoomUtil.intoRoom(groupName) && WeworkRoomUtil.intoGroupManager()) { + val tvList = AccessibilityUtil.findAllOnceByClazz(getRoot(), Views.TextView) + tvList.forEachIndexed { index, tv -> + if (tv.text != null && tv.text.contains("微信用户创建")) { + if (index + 1 < tvList.size) { + val tvQr = tvList[index + 1] + AccessibilityUtil.performClick(tvQr) + } + } + } + AccessibilityUtil.findOneByText(getRoot(), "保存到相册") + val startTime = System.currentTimeMillis() + var currentTime = startTime + while (currentTime - startTime <= Constant.CHANGE_PAGE_INTERVAL * 5) { + AccessibilityUtil.findOnceByClazz(getRoot(), Views.ProgressBar) ?: break + sleep(Constant.POP_WINDOW_INTERVAL / 5) + currentTime = System.currentTimeMillis() + } + if (AccessibilityUtil.findTextAndClick(getRoot(), "保存到相册")) { + sleep(Constant.CHANGE_PAGE_INTERVAL) + val fileDirPath = "/storage/emulated/0/DCIM/WeixinWork" + val fileDir = FileUtils.getFileByPath(fileDirPath) + if (fileDir.isDirectory) { + for (file in fileDir.listFiles().filter { it.name.endsWith(".jpg") }) { + val fileTime = file.name.replace("mmexport", "") + .replace(".jpg", "") + LogUtils.v("fileTime: $fileTime") + if (fileTime.isNotBlank()) { + if (fileTime.toLong() > currentTime) { + LogUtils.d("找到最新保存二维码图片: $fileTime") + try { + val bitmap = ImageUtils.bytes2Bitmap(file.readBytes()) + val mDecoder = QRCodeDecoder.Builder().build() + val qrcode = mDecoder.decode(bitmap) + LogUtils.e("group: $groupName qrcode: $qrcode") + val weworkMessageBean = WeworkMessageBean() + weworkMessageBean.type = WeworkMessageBean.GET_GROUP_QRCODE + weworkMessageBean.groupName = groupName + weworkMessageBean.qrcode = qrcode + WeworkController.weworkService.webSocketManager.send( + weworkMessageBean + ) + return true + } catch (e: Exception) { + e.printStackTrace() + LogUtils.e(e) + } + } + } + } + } + } + } + return false + } + /** * 进入群聊并修改群配置 * 群名称、群公告、拉人、踢人 @@ -284,12 +350,12 @@ object WeworkOperationImpl { val node = AccessibilityUtil.scrollAndFindByText(getRoot(), "用过的小程序") if (node != null) { AccessibilityUtil.performClick(node) + sleep(Constant.CHANGE_PAGE_INTERVAL) val textViewList = AccessibilityUtil.findAllByClazz(getRoot(), Views.TextView) if (textViewList.size > 3) { AccessibilityUtil.performClick(textViewList[2]) AccessibilityUtil.findTextInput(getRoot(), objectName) - sleep(2000) - AccessibilityUtil.findListOneAndClick(getRoot(), 1) + AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView) sleep(2000) //todo 转发小程序 return true diff --git a/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt b/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt index 77d3f67..c225739 100644 --- a/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt +++ b/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt @@ -1,11 +1,15 @@ package org.yameida.worktool.utils import android.accessibilityservice.AccessibilityService +import android.accessibilityservice.AccessibilityService.GestureResultCallback import android.accessibilityservice.GestureDescription +import android.accessibilityservice.GestureDescription.StrokeDescription import android.annotation.TargetApi import android.app.Notification import android.app.PendingIntent import android.graphics.Path +import android.graphics.Point +import android.graphics.Rect import android.os.Build import android.os.Bundle import android.util.Log @@ -15,6 +19,7 @@ import com.blankj.utilcode.util.LogUtils import org.yameida.worktool.service.getRoot import java.lang.Exception import java.lang.Thread.sleep +import androidx.annotation.RequiresApi /** * 1.查询类 @@ -639,4 +644,33 @@ object AccessibilityUtil { } } + /** + * Gesture手势实现点击(Android7+) + * 解决 clickable=false 无法点击问题 + */ + @RequiresApi(api = Build.VERSION_CODES.N) + fun clickByNode( + service: AccessibilityService, + nodeInfo: AccessibilityNodeInfo + ): Boolean { + val rect = Rect() + nodeInfo.getBoundsInScreen(rect) + val x: Int = (rect.left + rect.right) / 2 + val y: Int = (rect.top + rect.bottom) / 2 + val point = Point(x, y) + val builder = GestureDescription.Builder() + val path = Path() + path.moveTo(point.x.toFloat(), point.y.toFloat()) + builder.addStroke(StrokeDescription(path, 0L, 100L)) + val gesture = builder.build() + return service.dispatchGesture(gesture, object : GestureResultCallback() { + override fun onCompleted(gestureDescription: GestureDescription) { + LogUtils.e("click okk onCompleted") + } + + override fun onCancelled(gestureDescription: GestureDescription) { + LogUtils.e("click okk onCancelled") + } + }, null) + } } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/Views.java b/app/src/main/java/org/yameida/worktool/utils/Views.java index 1b02bac..9fc2f33 100644 --- a/app/src/main/java/org/yameida/worktool/utils/Views.java +++ b/app/src/main/java/org/yameida/worktool/utils/Views.java @@ -12,4 +12,5 @@ public class Views { public static String GridView = "android.widget.GridView"; public static String RelativeLayout = "android.widget.RelativeLayout"; public static String LinearLayout = "android.widget.LinearLayout"; + public static String ProgressBar = "android.widget.ProgressBar"; } diff --git a/app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java b/app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java index ff723db..9f38738 100644 --- a/app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java +++ b/app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java @@ -77,21 +77,21 @@ public class WebSocketManager { } public void send(WeworkMessageListBean msg) { - send(msg, false); + send(msg, msg.getSocketType() == 2); } public void send(WeworkMessageListBean msg, boolean log) { String json = GsonUtils.toJson(msg); - boolean suc = socket.send(json); - if (log) - LogUtils.v(url, json, (suc ? "通讯消息发送成功!" : "通讯消息发送失败!")); - else - LogUtils.e(url, json, (suc ? "通讯消息发送成功!" : "通讯消息发送失败!")); + boolean success = socket.send(json); + if (log && success) + LogUtils.d(url, json, "通讯消息发送成功!"); + if (!success) + LogUtils.e(url, json, "通讯消息发送失败!"); } public void send(String msg) { - boolean suc = socket.send(msg); - LogUtils.e(url, msg, (suc ? "通讯消息发送成功!" : "通讯消息发送失败!")); + boolean success = socket.send(msg); + LogUtils.e(url, msg, (success ? "通讯消息发送成功!" : "通讯消息发送失败!")); } public void close(int code, String reason) { diff --git a/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt b/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt index 43e679e..67fdf4c 100644 --- a/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt +++ b/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt @@ -100,14 +100,19 @@ object WeworkRoomUtil { sleep(Constant.CHANGE_PAGE_INTERVAL) val selectListView = findOneByClazz(getRoot(), Views.ListView) val imageView = AccessibilityUtil.findOnceByClazz(selectListView, Views.ImageView) - AccessibilityUtil.performClick(imageView) - sleep(Constant.CHANGE_PAGE_INTERVAL) - return true + if (imageView != null) { + AccessibilityUtil.performClick(imageView) + sleep(Constant.CHANGE_PAGE_INTERVAL) + return true + } else { + LogUtils.e("未搜索到结果") + } } else { LogUtils.e("未找到搜索按钮") } + } else { + LogUtils.e("未找到聊天列表") } - LogUtils.e("未找到聊天列表") return false } @@ -127,6 +132,7 @@ object WeworkRoomUtil { if (textViewList.size >= 2) { val multiButton = textViewList.lastOrNull() AccessibilityUtil.performClick(multiButton) + sleep(Constant.CHANGE_PAGE_INTERVAL) return true } else { LogUtils.e("未找到群管理按钮") @@ -180,6 +186,13 @@ object WeworkRoomUtil { return titleList } + /** + * 群名是否存在 + */ + fun isGroupExists(groupName: String): Boolean { + return intoRoom(groupName) + } + /** * 是否是群聊 * 群右上角有两个按钮(快速会议按钮、更多按钮)