diff --git a/app/build.gradle b/app/build.gradle index 301e65f..c757097 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "org.yameida.worktool" minSdkVersion 23 targetSdkVersion 30 - versionCode 2 - versionName "2.0" + versionCode 211 + versionName "2.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java b/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java index 31b7a98..37cd4d5 100644 --- a/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java +++ b/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java @@ -139,6 +139,8 @@ public class WeworkMessageBean { public String receivedName; //内容移除了@me public String receivedContent; + //想要at的昵称 + public String at; //原始内容text public String originalContent; //多选(转发等) @@ -231,6 +233,7 @@ public class WeworkMessageBean { public String corporation; public String phone; public String job; + public String sumInfo; } //添加好友 diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkController.kt b/app/src/main/java/org/yameida/worktool/service/WeworkController.kt index 57caeed..eb780a7 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkController.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkController.kt @@ -42,12 +42,13 @@ object WeworkController { * @see WeworkMessageBean.SEND_MESSAGE * @param message#titleList 房间名称 * @param message#receivedContent 回复内容 + * @param message#at 要at的昵称 * @see WeworkMessageBean.TEXT_TYPE */ @RequestMapping fun sendMessage(message: WeworkMessageBean): Boolean { - LogUtils.d("sendMessage(): ${message.titleList} ${message.receivedContent}") - return WeworkOperationImpl.sendMessage(message.titleList, message.receivedContent) + LogUtils.d("sendMessage(): ${message.titleList} ${message.receivedContent} ${message.at}") + return WeworkOperationImpl.sendMessage(message.titleList, message.receivedContent, message.at) } /** diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt b/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt index d1e69dd..2205100 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt @@ -7,6 +7,7 @@ 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 java.lang.StringBuilder /** * 获取数据类型 500 实现类 @@ -55,13 +56,34 @@ object WeworkGetImpl { sleep(Constant.CHANGE_PAGE_INTERVAL) val newFirstTv = AccessibilityUtil.findOneByClazz(getRoot(), Views.TextView) val nickname = newFirstTv?.text?.toString() - AccessibilityUtil.performClick(firstTv) if (nickname != null) { + var corp: String? = null + val info = StringBuilder() + if (AccessibilityUtil.performClick(newFirstTv)) { + sleep(Constant.CHANGE_PAGE_INTERVAL) + val rv = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView) + if (rv != null && rv.childCount > 0) { + val myInfoLayout = rv.getChild(0) + val tvList = AccessibilityUtil.findAllByClazz(myInfoLayout, Views.TextView) + .filter { it.text != null } + if (tvList.isNotEmpty()) { + corp = tvList[0].text.toString() + tvList.forEach { info.append(it.text).append("-") } + info.setLength(info.length - 1) + LogUtils.v("corp", corp) + LogUtils.v("info", info.toString()) + } + } + } Constant.myName = nickname LogUtils.d("我的昵称: ${Constant.myName}") val weworkMessageBean = WeworkMessageBean() weworkMessageBean.type = WeworkMessageBean.GET_MY_INFO - weworkMessageBean.myInfo = WeworkMessageBean.MyInfo().apply { name = nickname } + weworkMessageBean.myInfo = WeworkMessageBean.MyInfo().apply { + name = nickname + corporation = corp + sumInfo = info.toString() + } WeworkController.weworkService.webSocketManager.send(weworkMessageBean) return true } else { diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt b/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt index 3af2ef1..a051fc3 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt @@ -200,12 +200,31 @@ object WeworkLoopImpl { private fun getChatroomList(): Boolean { if (Constant.autoReply == 0) return true if (!isAtHome()) return true - if (logIndex % 3 == 0) { - AccessibilityUtil.performScrollUp(getRoot(), 0) - AccessibilityUtil.performScrollUp(getRoot(), 0) - AccessibilityUtil.performScrollUp(getRoot(), 0) - } else if (logIndex % 120 < 3) { - AccessibilityUtil.performScrollDown(getRoot(), 0) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + val list = AccessibilityUtil.findAllOnceByText(getRoot(), "消息", exact = true) + for (item in list) { + if (item.parent.parent.parent.childCount == 5) { + if (item.parent.childCount > 1) { + LogUtils.d("消息有红点") + AccessibilityUtil.clickByNode(WeworkController.weworkService, item) + sleep(100) + AccessibilityUtil.clickByNode(WeworkController.weworkService, item) + } + } + } + if (logIndex % 120 == 0) { + goHomeTab("通讯录") + goHomeTab("消息") + } + } else { + if (logIndex % 3 == 0) { + AccessibilityUtil.performScrollUp(getRoot(), 0) + AccessibilityUtil.performScrollUp(getRoot(), 0) + AccessibilityUtil.performScrollUp(getRoot(), 0) + } else if (logIndex % 120 < 3) { + AccessibilityUtil.performScrollDown(getRoot(), 0) + } } if (!isAtHome()) return true if (logIndex++ % 15 == 0) { 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 97f6152..f1f4f92 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt @@ -21,12 +21,13 @@ object WeworkOperationImpl { * 在房间内发送消息 * @param titleList 房间名称 * @param receivedContent 回复内容 + * @param at 要at的昵称 * @see WeworkMessageBean.TEXT_TYPE */ - fun sendMessage(titleList: List, receivedContent: String): Boolean { + fun sendMessage(titleList: List, receivedContent: String, at: String? = null): Boolean { for (title in titleList) { if (WeworkRoomUtil.intoRoom(title)) { - sendChatMessage(receivedContent) + sendChatMessage(receivedContent, at = at) LogUtils.d("$title: 发送成功") } else { LogUtils.d("$title: 发送失败") @@ -440,8 +441,9 @@ object WeworkOperationImpl { AccessibilityUtil.findTextAndClick(getRoot(), "搜索手机号添加") AccessibilityUtil.findTextInput(getRoot(), friend.phone.trim()) if (AccessibilityUtil.findTextAndClick(getRoot(), "网络查找手机")) { - val bothUsedTv = AccessibilityUtil.findOneByText(getRoot(), "对方同时使用", timeout = 2000) - if (bothUsedTv != null) { + val bothUsedTv = AccessibilityUtil.findOneByText(getRoot(), "对方同时使用", "标签", "电话") + val bothUsedText = bothUsedTv?.text + if (bothUsedText != null && bothUsedText.contains("对方同时使用")) { AccessibilityUtil.performClick( AccessibilityUtil.findOnceByClazz( AccessibilityUtil.findBackNode(bothUsedTv), @@ -449,72 +451,72 @@ object WeworkOperationImpl { ) ) } - } else { - LogUtils.e("未找到查找手机选项") - } - if (AccessibilityUtil.findOneByText(getRoot(), "标签") != null) { - var markTv = AccessibilityUtil.findOnceByText(getRoot(), "设置备注和描述") - if (markTv == null) { - markTv = AccessibilityUtil.findOnceByText(getRoot(), "企业") - } - if (markTv == null) { - markTv = AccessibilityUtil.findOnceByText(getRoot(), "描述") - } - //设置备注 - if (markTv != null && (friend.markName != null - || friend.markCorp != null || friend.markExtra != null) - ) { - AccessibilityUtil.performClick(markTv) - val etList = - AccessibilityUtil.findAllByClazz(getRoot(), Views.EditText, minSize = 5) - if (etList.size >= 5) { - if (friend.markName != null) { - AccessibilityUtil.editTextInput(etList[0], friend.markName) + if (AccessibilityUtil.findOneByText(getRoot(), "标签", "电话") != null) { + var markTv = AccessibilityUtil.findOnceByText(getRoot(), "设置备注和描述") + if (markTv == null) { + markTv = AccessibilityUtil.findOnceByText(getRoot(), "企业") + } + if (markTv == null) { + markTv = AccessibilityUtil.findOnceByText(getRoot(), "描述") + } + //设置备注 + if (markTv != null && (friend.markName != null + || friend.markCorp != null || friend.markExtra != null) + ) { + AccessibilityUtil.performClick(markTv) + val etList = + AccessibilityUtil.findAllByClazz(getRoot(), Views.EditText, minSize = 5) + if (etList.size >= 5) { + if (friend.markName != null) { + AccessibilityUtil.editTextInput(etList[0], friend.markName) + } + if (friend.markCorp != null) { + AccessibilityUtil.editTextInput(etList[1], friend.markCorp) + } + if (friend.markExtra != null) { + AccessibilityUtil.editTextInput(etList[4], friend.markExtra) + } } - if (friend.markCorp != null) { - AccessibilityUtil.editTextInput(etList[1], friend.markCorp) - } - if (friend.markExtra != null) { - AccessibilityUtil.editTextInput(etList[4], friend.markExtra) + AccessibilityUtil.findTextAndClick(getRoot(), "保存") + } + //设置标签 + if (!friend.tagList.isNullOrEmpty()) { + if (AccessibilityUtil.findTextAndClick(getRoot(), "标签")) { + setFriendTags(friend.tagList) } } - AccessibilityUtil.findTextAndClick(getRoot(), "保存") - } - //设置标签 - if (!friend.tagList.isNullOrEmpty()) { - if (AccessibilityUtil.findTextAndClick(getRoot(), "标签")) { - setFriendTags(friend.tagList) + //添加联系人 + val imageView = + AccessibilityUtil.findOneByClazz(getRoot(), Views.ImageView) + if (imageView != null) { + val textViewList = AccessibilityUtil.findAllOnceByClazz( + imageView.parent, + Views.TextView + ) + val filter = + textViewList.filter { it.text != null && it.text.toString() != "微信" } + if (filter.isNotEmpty()) { + val tvNick = filter[0] + LogUtils.d("好友昵称或备注名: " + tvNick.text) + } } - } - //添加联系人 - val imageView = - AccessibilityUtil.findOneByClazz(getRoot(), Views.ImageView) - if (imageView != null) { - val textViewList = AccessibilityUtil.findAllOnceByClazz( - imageView.parent, - Views.TextView - ) - val filter = - textViewList.filter { it.text != null && it.text.toString() != "微信" } - if (filter.isNotEmpty()) { - val tvNick = filter[0] - LogUtils.d("好友昵称或备注名: " + tvNick.text) - } - } - if (AccessibilityUtil.findTextAndClick(getRoot(), "添加为联系人")) { - LogUtils.d("添加好友成功: " + friend.phone) - if (AccessibilityUtil.findTextAndClick(getRoot(), "发送添加邀请", "发送申请")) { - LogUtils.d("发送添加邀请成功: " + friend.phone) + if (AccessibilityUtil.findTextAndClick(getRoot(), "添加为联系人")) { + LogUtils.d("添加好友成功: " + friend.phone) + if (AccessibilityUtil.findTextAndClick(getRoot(), "发送添加邀请", "发送申请")) { + LogUtils.d("发送添加邀请成功: " + friend.phone) + } + } else { + if (AccessibilityUtil.findOnceByText(getRoot(), "发消息") != null) { + LogUtils.e("已经添加联系人,请勿重复添加") + } else { + LogUtils.e("未找到添加为联系人") + } } } else { - if (AccessibilityUtil.findOnceByText(getRoot(), "发消息") != null) { - LogUtils.e("已经添加联系人,请勿重复添加") - } else { - LogUtils.e("未找到添加为联系人") - } + LogUtils.e("未找到标签") } } else { - LogUtils.e("未找到标签") + LogUtils.e("未找到查找手机选项") } } else { LogUtils.e("未找到添加客户按钮") @@ -821,10 +823,29 @@ object WeworkOperationImpl { } /** - * 发送消息 + * 发送消息+@at */ - private fun sendChatMessage(text: String, prefix: String = "") { - if (AccessibilityUtil.findTextInput(getRoot(), prefix + text)) { + private fun sendChatMessage(text: String, prefix: String = "", at: String? = null) { + var atFailed = false + if (!at.isNullOrEmpty()) { + AccessibilityUtil.findTextInput(getRoot(), "@") + val atFlag = AccessibilityUtil.findOneByText(getRoot(), "选择提醒的人", timeout = 2000) + if (atFlag != null) { + val rv = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView) + AccessibilityUtil.findTextInput(getRoot(), at) + val atNode = AccessibilityUtil.findOneByText(rv, at, root = false, timeout = 2000) + if (atNode != null) { + AccessibilityUtil.performClick(atNode) + } else { + LogUtils.e("未找到at人: $at") + atFailed = true + backPress() + } + sleep(Constant.POP_WINDOW_INTERVAL) + } + } + val content = if (atFailed) "@$at $prefix$text" else "$prefix$text" + if (AccessibilityUtil.findTextInput(getRoot(), content, append = !atFailed)) { val sendButton = AccessibilityUtil.findAllByClazz(getRoot(), Views.Button) .firstOrNull { it.text == "发送" } if (sendButton != null) { 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 7683082..645c438 100644 --- a/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt +++ b/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt @@ -76,24 +76,21 @@ object AccessibilityUtil { } //寻找第一个EditView编辑框并输入文本 - fun findTextInput(nodeInfo: AccessibilityNodeInfo?, text: String, root: Boolean = true): Boolean { - if (root) { - val editText = findOneByClazz(nodeInfo, "android.widget.EditText") ?: return false - val arguments = Bundle() - arguments.putCharSequence( - AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, - text - ) - editText.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments) + fun findTextInput(nodeInfo: AccessibilityNodeInfo?, text: String, root: Boolean = true, append: Boolean = false): Boolean { + val editText = if (root) { + findOneByClazz(nodeInfo, "android.widget.EditText") ?: return false } else { - val editText = findOnceByClazz(nodeInfo, "android.widget.EditText") ?: return false - val arguments = Bundle() - arguments.putCharSequence( - AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, - text - ) - editText.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments) + findOnceByClazz(nodeInfo, "android.widget.EditText") ?: return false } + editText.refresh() + val oldText = if (editText.text != null) editText.text.toString() else "" + LogUtils.v("findTextInput oldText: $oldText") + val arguments = Bundle() + arguments.putCharSequence( + AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, + if (append) (oldText + text) else text + ) + editText.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments) return true } @@ -710,15 +707,15 @@ object AccessibilityUtil { val builder = GestureDescription.Builder() val path = Path() path.moveTo(point.x.toFloat(), point.y.toFloat()) - builder.addStroke(StrokeDescription(path, 0L, 100L)) + builder.addStroke(StrokeDescription(path, 0L, 10L)) val gesture = builder.build() return service.dispatchGesture(gesture, object : GestureResultCallback() { override fun onCompleted(gestureDescription: GestureDescription) { - LogUtils.e("click okk onCompleted") + LogUtils.d("click okk onCompleted") } override fun onCancelled(gestureDescription: GestureDescription) { - LogUtils.e("click okk onCancelled") + LogUtils.d("click okk onCancelled") } }, null) }