diff --git a/app/src/main/java/org/yameida/worktool/Constant.kt b/app/src/main/java/org/yameida/worktool/Constant.kt index 2512b84..caee968 100644 --- a/app/src/main/java/org/yameida/worktool/Constant.kt +++ b/app/src/main/java/org/yameida/worktool/Constant.kt @@ -1,21 +1,34 @@ package org.yameida.worktool import com.blankj.utilcode.util.SPUtils -import org.yameida.worktool.config.WebConfig object Constant { - val AVAILABLE_VERSION = arrayListOf("4.0.2", "4.0.6", "4.0.8", "4.0.10", "4.0.12") + val AVAILABLE_VERSION = arrayListOf("4.0.2", "4.0.6", "4.0.8", "4.0.10", "4.0.12", "4.0.16") const val PACKAGE_NAMES = "com.tencent.wework" - val BASE_URL = WebConfig.HOST.replace("wss", "https").replace("ws", "http") - val URL_CHECK_UPDATE = "$BASE_URL/appUpdate/checkUpdate" + const val LISTEN_CHANNEL_ID = "LISTEN_CHANNEL_ID" + const val WEWORK_NOTIFY = "wework_notify" const val CHANGE_PAGE_INTERVAL = 1000L const val POP_WINDOW_INTERVAL = 500L + private const val DEFAULT_HOST = "wss://worktool.asrtts.cn" var myName = "" + var regTrimTitle = "(…$)|(-.*$)|(\\(.*?\\)$)".toRegex() var key = "9876543210abcdef".toByteArray() var iv = "0123456789abcdef".toByteArray() val transformation = "AES/CBC/PKCS7Padding" var encryptType = SPUtils.getInstance().getInt("encryptType", 1) var autoReply = SPUtils.getInstance().getInt("autoReply", 1) + var host: String + get() = SPUtils.getInstance().getString("host", DEFAULT_HOST) + set(value) { + SPUtils.getInstance().put("host", value) + } + + fun getWsUrl() = "$host/webserver/wework/" + SPUtils.getInstance().getString(Constant.LISTEN_CHANNEL_ID) + + fun getCheckUpdateUrl() = "${getBaseUrl()}/appUpdate/checkUpdate" + + private fun getBaseUrl() = host.replace("wss", "https").replace("ws", "http") + } diff --git a/app/src/main/java/org/yameida/worktool/activity/ListenActivity.kt b/app/src/main/java/org/yameida/worktool/activity/ListenActivity.kt index 68ca9e3..9b94fcf 100644 --- a/app/src/main/java/org/yameida/worktool/activity/ListenActivity.kt +++ b/app/src/main/java/org/yameida/worktool/activity/ListenActivity.kt @@ -15,8 +15,11 @@ import com.umeng.analytics.MobclickAgent import kotlinx.android.synthetic.main.activity_listen.* import org.yameida.worktool.* import org.yameida.worktool.service.WeworkService -import org.yameida.worktool.config.WebConfig import org.yameida.worktool.utils.UpdateUtil +import android.app.Dialog +import android.widget.Button +import android.widget.EditText + class ListenActivity : AppCompatActivity() { @@ -42,12 +45,12 @@ class ListenActivity : AppCompatActivity() { } private fun initView() { - et_channel.setText(SPUtils.getInstance().getString(WebConfig.LISTEN_CHANNEL_ID)) + et_channel.setText(SPUtils.getInstance().getString(Constant.LISTEN_CHANNEL_ID)) bt_save.setOnClickListener { val channel = et_channel.text.toString().trim() - SPUtils.getInstance().put(WebConfig.LISTEN_CHANNEL_ID, channel) + SPUtils.getInstance().put(Constant.LISTEN_CHANNEL_ID, channel) ToastUtils.showLong("保存成功") - sendBroadcast(Intent(WebConfig.WEWORK_NOTIFY).apply { + sendBroadcast(Intent(Constant.WEWORK_NOTIFY).apply { putExtra("type", "modify_channel") }) MobclickAgent.onProfileSignIn(channel) @@ -64,7 +67,11 @@ class ListenActivity : AppCompatActivity() { Constant.autoReply = if (isChecked) 1 else 0 SPUtils.getInstance().put("autoReply", Constant.autoReply) }) - tv_host.text = WebConfig.HOST + tv_host.text = Constant.host + tv_host.setOnLongClickListener { + showInputDialog() + true + } val version = "${AppUtils.getAppVersionName()} Android ${DeviceUtils.getSDKVersionName()} ${DeviceUtils.getManufacturer()} ${DeviceUtils.getModel()}" tv_version.text = version val workVersionName = AppUtils.getAppInfo(Constant.PACKAGE_NAMES)?.versionName @@ -92,7 +99,7 @@ class ListenActivity : AppCompatActivity() { sw_accessibility.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked -> LogUtils.i("sw_accessibility onCheckedChanged: $isChecked") if (isChecked) { - if (SPUtils.getInstance().getString(WebConfig.LISTEN_CHANNEL_ID).isNullOrBlank()) { + if (SPUtils.getInstance().getString(Constant.LISTEN_CHANNEL_ID).isNullOrBlank()) { sw_accessibility.isChecked = false ToastUtils.showLong("请先填写并保存链接号~") } else if (!isAccessibilitySettingOn()) { @@ -193,4 +200,32 @@ class ListenActivity : AppCompatActivity() { } } + private fun showInputDialog() { + ToastUtils.showLong("请输入专线网络") + val commentDialog = Dialog(this) + commentDialog.setContentView(R.layout.dialog_input) + val et: EditText = commentDialog.findViewById(R.id.body) as EditText + val okBtn: Button = commentDialog.findViewById(R.id.ok) as Button + okBtn.setOnClickListener { + val text = et.text.toString() + if (text.isNotBlank()) { + if (text.matches("ws{1,2}://[^/]+.*".toRegex())) { + Constant.host = text + tv_host.text = text + ToastUtils.showLong("保存成功") + commentDialog.dismiss() + } else { + ToastUtils.showLong("格式异常!") + } + } else { + ToastUtils.showLong("请勿为空!") + } + } + val cancelBtn: Button = commentDialog.findViewById(R.id.cancel) as Button + cancelBtn.setOnClickListener { + commentDialog.dismiss() + } + commentDialog.show() + } + } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/config/WebConfig.java b/app/src/main/java/org/yameida/worktool/config/WebConfig.java deleted file mode 100644 index a792f15..0000000 --- a/app/src/main/java/org/yameida/worktool/config/WebConfig.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.yameida.worktool.config; -public class WebConfig { - public static final String WEWORK_NOTIFY = "wework_notify"; - - public static final String HOST = "wss://worktool.asrtts.cn"; - public static final String WEWORK_URL = HOST + "/webserver/wework/"; - public static String LISTEN_CHANNEL_ID = "LISTEN_CHANNEL_ID"; -} 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 345a1ba..1382685 100644 --- a/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java +++ b/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java @@ -139,8 +139,6 @@ public class WeworkMessageBean { public String receivedName; //内容移除了@me public String receivedContent; - //回复内容前缀 - public String prefix; //想要at的昵称 public String at; //原始内容text @@ -254,6 +252,8 @@ public class WeworkMessageBean { public List tagList; //是否是新好友 public Boolean newFriend; + //留言 + public String leavingMsg; } @Override @@ -266,7 +266,7 @@ public class WeworkMessageBean { @Override public int hashCode() { - return Objects.hash(titleList, messageList, log, roomType, receivedName, receivedContent, originalContent, nameList, extraText, textType, groupName, groupOwner, selectList, groupNumber, groupAnnouncement, newGroupName, newGroupAnnouncement, removeList, showMessageHistory, myInfo, objectName, type); + return Objects.hash(titleList, messageList, log, roomType, receivedName, receivedContent, originalContent, nameList, extraText, textType, groupName, groupOwner, selectList, groupNumber, groupAnnouncement, newGroupName, newGroupAnnouncement, removeList, showMessageHistory, myInfo, objectName, type, friend); } @Override diff --git a/app/src/main/java/org/yameida/worktool/service/GlobalMethod.kt b/app/src/main/java/org/yameida/worktool/service/GlobalMethod.kt index fd48866..dd50802 100644 --- a/app/src/main/java/org/yameida/worktool/service/GlobalMethod.kt +++ b/app/src/main/java/org/yameida/worktool/service/GlobalMethod.kt @@ -107,23 +107,23 @@ fun getRoot(ignoreCheck: Boolean): AccessibilityNodeInfo { */ fun backPress() { val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView) - if (textView != null && textView.text.isNullOrBlank() && AccessibilityUtil.performClick(textView)) { + if (textView != null && textView.text.isNullOrBlank() && AccessibilityUtil.performClick(textView, retry = false)) { LogUtils.v("找到回退按钮") } else { val ivButton = AccessibilityUtil.findOnceByClazz(getRoot(), Views.ImageView) if (ivButton != null && ivButton.isClickable && AccessibilityUtil.findFrontNode(ivButton) == null) { LogUtils.d("未找到回退按钮 点击第一个IV按钮") - AccessibilityUtil.performClick(ivButton) + AccessibilityUtil.performClick(ivButton, retry = false) } else { LogUtils.d("未找到回退按钮 点击第一个BT按钮") val button = AccessibilityUtil.findOnceByClazz(getRoot(), Views.Button) if (button != null && button.childCount > 0) { - AccessibilityUtil.performClick(button.getChild(0)) + AccessibilityUtil.performClick(button.getChild(0), retry = false) } else if (button != null) { - AccessibilityUtil.performClick(button) + AccessibilityUtil.performClick(button, retry = false) } else { LogUtils.d("未找到BT按钮") - val confirm = AccessibilityUtil.findOnceByText(getRoot(), "确定", "我知道了", "暂不进入", "不用了", "取消") + val confirm = AccessibilityUtil.findOnceByText(getRoot(), "确定", "我知道了", "暂不进入", "不用了", "取消", "暂不", exact = true) if (confirm != null) { LogUtils.d("尝试点击确定/我知道了/暂不进入") AccessibilityUtil.performClick(confirm) diff --git a/app/src/main/java/org/yameida/worktool/service/MyLooper.kt b/app/src/main/java/org/yameida/worktool/service/MyLooper.kt index 1ea0976..8cc85d6 100644 --- a/app/src/main/java/org/yameida/worktool/service/MyLooper.kt +++ b/app/src/main/java/org/yameida/worktool/service/MyLooper.kt @@ -80,7 +80,6 @@ object MyLooper { WeworkController.enableLoopRunning = true } else { WeworkController.mainLoopRunning = false - getInstance().removeMessages(message.type * message.hashCode()) getInstance().sendMessage(Message.obtain().apply { what = message.type * message.hashCode() obj = message 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 f2aa5be..eb780a7 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkController.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkController.kt @@ -59,7 +59,6 @@ object WeworkController { * @param message#originalContent 原始消息的内容 * @param message#textType 原始消息的消息类型 * @param message#receivedContent 回复内容 - * @param message#prefix 回复内容前缀 * @see WeworkMessageBean.TEXT_TYPE */ @RequestMapping 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 880967d..0022da0 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt @@ -53,7 +53,7 @@ object WeworkGetImpl { goHomeTab("消息") val firstTv = AccessibilityUtil.findAllByClazz(getRoot(), Views.TextView) .firstOrNull { it.text == null } - AccessibilityUtil.performClick(firstTv) + AccessibilityUtil.performClick(firstTv, retry = false) sleep(Constant.CHANGE_PAGE_INTERVAL) val newFirstTv = AccessibilityUtil.findOneByClazz(getRoot(), Views.TextView) val nickname = newFirstTv?.text?.toString() 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 a088247..9042b8e 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt @@ -1,6 +1,5 @@ package org.yameida.worktool.service -import android.os.Build import android.view.accessibility.AccessibilityNodeInfo import androidx.core.text.isDigitsOnly import com.blankj.utilcode.util.LogUtils @@ -185,7 +184,7 @@ object WeworkLoopImpl { //回到上一页 var retry = 5 while (retry-- > 0 && !isAtHome()) { - val textView = AccessibilityUtil.findOnceByText(getRoot(), "新的客户", "新的居民", exact = true) + val textView = AccessibilityUtil.findOnceByText(getRoot(), "新的客户", "新的居民", "新的学员", exact = true) if (textView == null) { backPress() } @@ -202,30 +201,20 @@ object WeworkLoopImpl { if (Constant.autoReply == 0) return true if (!isAtHome()) return true - 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) - } + 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 (logIndex % 120 == 0) { + goHomeTab("通讯录") + goHomeTab("消息") } if (!isAtHome()) return true if (logIndex++ % 30 == 0) { @@ -277,12 +266,7 @@ object WeworkLoopImpl { 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可用)") - } + AccessibilityUtil.clickByNode(WeworkController.weworkService, spotNodeList.first().parent) } return true } else { 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 14ad967..6c1ed9c 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt @@ -1,6 +1,5 @@ package org.yameida.worktool.service -import android.os.Build import android.view.accessibility.AccessibilityNodeInfo import org.yameida.worktool.Constant import org.yameida.worktool.model.WeworkMessageBean @@ -25,7 +24,11 @@ object WeworkOperationImpl { * @param at 要at的昵称 * @see WeworkMessageBean.TEXT_TYPE */ - fun sendMessage(titleList: List, receivedContent: String, at: String? = null): Boolean { + fun sendMessage(titleList: List, receivedContent: String?, at: String? = null): Boolean { + if (receivedContent.isNullOrEmpty()) { + LogUtils.d("未发现发送内容") + return false + } for (title in titleList) { if (WeworkRoomUtil.intoRoom(title)) { sendChatMessage(receivedContent, at = at) @@ -45,7 +48,6 @@ object WeworkOperationImpl { * @param originalContent 原始消息的内容 * @param textType 原始消息的消息类型 * @param receivedContent 回复内容 - * @param prefix 回复内容前缀 * @see WeworkMessageBean.TEXT_TYPE */ fun replyMessage( @@ -53,9 +55,12 @@ object WeworkOperationImpl { receivedName: String?, originalContent: String, textType: Int, - receivedContent: String, - prefix: String = "[自动回复]" + receivedContent: String? ): Boolean { + if (receivedContent.isNullOrEmpty()) { + LogUtils.d("未发现回复内容") + return false + } for (title in titleList) { if (WeworkRoomUtil.intoRoom(title)) { if (WeworkTextUtil.longClickMessageItem( @@ -68,17 +73,25 @@ object WeworkOperationImpl { ) ) { LogUtils.v("开始回复") - sendChatMessage(receivedContent, prefix) + sendChatMessage(receivedContent, reply = true) LogUtils.d("$title: 回复成功") WeworkLoopImpl.getChatMessageList() return true } else { LogUtils.d("$title: 回复失败 直接发送答案") error("$title: 回复失败 直接发送答案 $receivedContent") - if (receivedName == null) { - sendChatMessage(receivedContent, "$prefix【$originalContent】\n") + if (originalContent.isNotEmpty()) { + if (receivedName == null) { + sendChatMessage("【$originalContent】\n$receivedContent") + } else { + sendChatMessage("【$originalContent】\n$receivedContent", receivedName) + } } else { - sendChatMessage(receivedContent, "$prefix【$originalContent】@$receivedName\n") + if (receivedName == null) { + sendChatMessage(receivedContent) + } else { + sendChatMessage(receivedContent, receivedName) + } } WeworkLoopImpl.getChatMessageList() } @@ -167,7 +180,8 @@ object WeworkOperationImpl { || !groupChangeAnnouncement(groupAnnouncement) ) return false } - getGroupQrcode(groupName) + //TODO 暂移除获取群二维码 +// getGroupQrcode(groupName) return true } @@ -222,15 +236,8 @@ object WeworkOperationImpl { goHomeTab("工作台") val node = AccessibilityUtil.scrollAndFindByText(WeworkController.weworkService, getRoot(), "微盘") if (node != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - AccessibilityUtil.performClick(node) - sleep(Constant.POP_WINDOW_INTERVAL) - if (AccessibilityUtil.findOnceByText(getRoot(), "微盘", exact = true) != null) { - AccessibilityUtil.clickByNode(WeworkController.weworkService, node) - } - } else { - AccessibilityUtil.performClick(node) - } + AccessibilityUtil.performClick(node) + sleep(Constant.POP_WINDOW_INTERVAL) val buttonList = AccessibilityUtil.findAllByClazz(getRoot(), Views.Button) if (buttonList.size >= 4) { AccessibilityUtil.performClick(buttonList[2]) @@ -272,15 +279,8 @@ object WeworkOperationImpl { goHomeTab("工作台") val node = AccessibilityUtil.scrollAndFindByText(WeworkController.weworkService, getRoot(), "微盘") if (node != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - AccessibilityUtil.performClick(node) - sleep(Constant.POP_WINDOW_INTERVAL) - if (AccessibilityUtil.findOnceByText(getRoot(), "微盘", exact = true) != null) { - AccessibilityUtil.clickByNode(WeworkController.weworkService, node) - } - } else { - AccessibilityUtil.performClick(node) - } + AccessibilityUtil.performClick(node) + sleep(Constant.POP_WINDOW_INTERVAL) val buttonList = AccessibilityUtil.findAllByClazz(getRoot(), Views.Button) if (buttonList.size >= 4) { AccessibilityUtil.performClick(buttonList[2]) @@ -401,17 +401,10 @@ object WeworkOperationImpl { sleep(Constant.POP_WINDOW_INTERVAL) val list = AccessibilityUtil.findAllByClazz(getRoot(), Views.ListView).lastOrNull() if (list != null) { - val button = AccessibilityUtil.findOneByText(list, "添加客户", "添加居民", "加微信") + val button = AccessibilityUtil.findOneByText(list, "添加客户", "添加居民", "加微信", "加学员", exact = true) if (button != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - AccessibilityUtil.performClick(button) - sleep(Constant.POP_WINDOW_INTERVAL) - if (AccessibilityUtil.findOnceByText(list, "添加客户", "添加居民", "加微信", exact = true) != null) { - AccessibilityUtil.clickByNode(WeworkController.weworkService, button) - } - } else { - AccessibilityUtil.performClick(button) - } + AccessibilityUtil.performClick(button) + sleep(Constant.POP_WINDOW_INTERVAL) AccessibilityUtil.findTextAndClick(getRoot(), "搜索手机号添加") AccessibilityUtil.findTextInput(getRoot(), friend.phone.trim()) if (AccessibilityUtil.findTextAndClick(getRoot(), "网络查找手机")) { @@ -475,7 +468,10 @@ object WeworkOperationImpl { } } if (AccessibilityUtil.findTextAndClick(getRoot(), "添加为联系人")) { - LogUtils.d("添加好友成功: " + friend.phone) + LogUtils.d("准备发送好友邀请: " + friend.phone) + if (!friend.leavingMsg.isNullOrEmpty()) { + AccessibilityUtil.findTextInput(getRoot(), friend.leavingMsg) + } if (AccessibilityUtil.findTextAndClick(getRoot(), "发送添加邀请", "发送申请")) { LogUtils.d("发送添加邀请成功: " + friend.phone) } @@ -553,17 +549,39 @@ object WeworkOperationImpl { AccessibilityUtil.performClick(multiButton) AccessibilityUtil.performClick(searchButton) for (select in selectList) { - AccessibilityUtil.findTextInput(getRoot(), select.replace("…", "").replace("-.*$".toRegex(), "")) - sleep(Constant.CHANGE_PAGE_INTERVAL * 2) - val selectListView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView, Views.RecyclerView, Views.ViewGroup, minChildCount = 2) - val imageView = AccessibilityUtil.findOneByClazz(selectListView, Views.ImageView) - if (imageView != null) { - AccessibilityUtil.performClick(imageView) - } + val needTrim = select.contains(Constant.regTrimTitle) + val trimTitle = select.replace(Constant.regTrimTitle, "") + AccessibilityUtil.findTextInput(getRoot(), trimTitle) sleep(Constant.CHANGE_PAGE_INTERVAL) + val selectListView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView, Views.RecyclerView, Views.ViewGroup, minChildCount = 2) + val regex = "^$trimTitle(-.*)?(…)?(\\(.*?\\))?" + if (needTrim) "" else "$" + val matchSelect = AccessibilityUtil.findOneByTextRegex( + selectListView, + regex, + timeout = 2000, + root = false + ) + if (selectListView != null && matchSelect != null) { + for (i in 0 until selectListView.childCount) { + val item = selectListView.getChild(i) + val searchResult = AccessibilityUtil.findOnceByTextRegex(item, regex) + if (searchResult != null) { + item.refresh() + val imageView = + AccessibilityUtil.findOneByClazz(item, Views.ImageView, root = false) + AccessibilityUtil.performClick(imageView) + } + } + } + if (matchSelect != null) { + LogUtils.d("找到搜索结果: $select") + } else { + LogUtils.e("未搜索到结果") + } + sleep(Constant.POP_WINDOW_INTERVAL) } val confirmButton = - AccessibilityUtil.findOneByText(getRoot(), "确定(${selectList.size})") + AccessibilityUtil.findOneByTextRegex(getRoot(), "^确定(\\(.*?\\))?\$") if (confirmButton != null) { AccessibilityUtil.performClick(confirmButton) sleep(Constant.POP_WINDOW_INTERVAL) @@ -571,12 +589,10 @@ object WeworkOperationImpl { LogUtils.d("extraText: $extraText") AccessibilityUtil.findTextInput(getRoot(), extraText) } - val sendButtonList = AccessibilityUtil.findAllByText(getRoot(), "发送") - for (sendButton in sendButtonList.filter { it.text != null }) { - if (sendButton.text == "发送" || sendButton.text == "发送(${selectList.size})") { - AccessibilityUtil.performClick(sendButton) - return true - } + val sendButton = AccessibilityUtil.findOneByTextRegex(getRoot(), "^发送(\\(.*?\\))?\$") + if (sendButton != null) { + AccessibilityUtil.performClick(sendButton) + return true } LogUtils.e("未发现发送按钮: ") return false @@ -598,28 +614,14 @@ object WeworkOperationImpl { */ private fun createGroup(): Boolean { goHomeTab("工作台") - val node = AccessibilityUtil.scrollAndFindByText(WeworkController.weworkService, getRoot(), "客户群", "居民群") + val node = AccessibilityUtil.scrollAndFindByText(WeworkController.weworkService, getRoot(), "客户群", "居民群", "学员群") if (node != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - AccessibilityUtil.performClick(node) - sleep(Constant.POP_WINDOW_INTERVAL) - if (AccessibilityUtil.findOnceByText(getRoot(), "客户群", "居民群", exact = true) != null) { - if (AccessibilityUtil.clickByNode(WeworkController.weworkService, node)) { - LogUtils.d("进入客户群应用") - val textView = - AccessibilityUtil.findOneByText(getRoot(), "创建一个客户群", "创建一个居民群") - return AccessibilityUtil.performClick(textView) - } - } else { - LogUtils.d("进入客户群应用") - val textView = AccessibilityUtil.findOneByText(getRoot(), "创建一个客户群", "创建一个居民群") - return AccessibilityUtil.performClick(textView) - } - } else if (AccessibilityUtil.performClick(node)) { - LogUtils.d("进入客户群应用") - val textView = AccessibilityUtil.findOneByText(getRoot(), "创建一个客户群", "创建一个居民群") - return AccessibilityUtil.performClick(textView) - } + AccessibilityUtil.performClick(node) + sleep(Constant.POP_WINDOW_INTERVAL) + LogUtils.d("进入客户群应用") + val textView = + AccessibilityUtil.findOneByText(getRoot(), "创建一个客户群", "创建一个居民群", "创建一个学员群") + return AccessibilityUtil.performClick(textView) } LogUtils.e("未找到客户群应用") log("未找到客户群应用") @@ -696,28 +698,47 @@ object WeworkOperationImpl { if (textViewList.size >= 2) { val multiButton = textViewList.lastOrNull() for (select in selectList) { + val needTrim = select.contains(Constant.regTrimTitle) + val trimTitle = select.replace(Constant.regTrimTitle, "") AccessibilityUtil.performClick(multiButton) - AccessibilityUtil.findTextInput(getRoot(), select) + AccessibilityUtil.findTextInput(getRoot(), trimTitle) sleep(Constant.POP_WINDOW_INTERVAL) - val selectListView = - AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView, Views.RecyclerView, Views.ViewGroup, minChildCount = 2) - if (selectListView != null) { - val imageView = - AccessibilityUtil.findOneByClazz(selectListView, Views.ImageView, root = false) - AccessibilityUtil.performClick(imageView) - val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView) - if (textView != null && textView.text.isNullOrBlank()) { - AccessibilityUtil.performClick(textView) + val selectListView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView, Views.RecyclerView, Views.ViewGroup, minChildCount = 2, firstChildClazz = Views.TextView) + val regex = "^$trimTitle(-.*)?(…)?(\\(.*?\\))?" + if (needTrim) "" else "$" + val matchSelect = AccessibilityUtil.findOneByTextRegex( + selectListView, + regex, + timeout = 2000, + root = false + ) + if (selectListView != null && matchSelect != null) { + for (i in 0 until selectListView.childCount) { + val item = selectListView.getChild(i) + val searchResult = AccessibilityUtil.findOnceByTextRegex(item, regex) + if (searchResult != null) { + item.refresh() + val imageView = + AccessibilityUtil.findOneByClazz(item, Views.ImageView, root = false) + AccessibilityUtil.performClick(imageView) + } } + } + val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView) + if (textView != null && textView.text.isNullOrBlank()) { + AccessibilityUtil.performClick(textView) + sleep(Constant.POP_WINDOW_INTERVAL) + } + if (matchSelect != null) { + LogUtils.d("找到搜索结果: $select") } else { - LogUtils.e("未查到列表结果") + LogUtils.e("未搜索到结果") } } if (showMessageHistory) { AccessibilityUtil.findTextAndClick(getRoot(), "聊天记录") } val confirmButton = - AccessibilityUtil.findOneByText(getRoot(), "确定(${selectList.size})") + AccessibilityUtil.findOneByTextRegex(getRoot(), "^确定(\\(.*?\\))?\$") if (confirmButton != null) { AccessibilityUtil.performClick(confirmButton) } else { @@ -764,21 +785,44 @@ object WeworkOperationImpl { if (textViewList.size >= 2) { val multiButton = textViewList.lastOrNull() for (select in removeList) { + val needTrim = select.contains(Constant.regTrimTitle) + val trimTitle = select.replace(Constant.regTrimTitle, "") AccessibilityUtil.performClick(multiButton) - AccessibilityUtil.findTextInput(getRoot(), select) + AccessibilityUtil.findTextInput(getRoot(), trimTitle) sleep(Constant.POP_WINDOW_INTERVAL) - val selectListView = - AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView, Views.RecyclerView, Views.ViewGroup, minChildCount = 2) - val imageView = - AccessibilityUtil.findOneByClazz(selectListView, Views.ImageView, root = false) - AccessibilityUtil.performClick(imageView) + val selectListView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView, Views.RecyclerView, Views.ViewGroup, minChildCount = 2, firstChildClazz = Views.RelativeLayout) + val regex = "^$trimTitle(-.*)?(…)?(\\(.*?\\))?" + if (needTrim) "" else "$" + val matchSelect = AccessibilityUtil.findOneByTextRegex( + selectListView, + regex, + timeout = 2000, + root = false + ) + if (selectListView != null && matchSelect != null) { + for (i in 0 until selectListView.childCount) { + val item = selectListView.getChild(i) + val searchResult = AccessibilityUtil.findOnceByTextRegex(item, regex) + if (searchResult != null) { + item.refresh() + val imageView = + AccessibilityUtil.findOneByClazz(item, Views.ImageView, root = false) + AccessibilityUtil.performClick(imageView) + } + } + } val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView) if (textView != null && textView.text.isNullOrBlank()) { AccessibilityUtil.performClick(textView) + sleep(Constant.POP_WINDOW_INTERVAL) + } + if (matchSelect != null) { + LogUtils.d("找到搜索结果: $select") + } else { + LogUtils.e("未搜索到结果") } } val confirmButton = - AccessibilityUtil.findOneByText(getRoot(), "移出(${removeList.size})") + AccessibilityUtil.findOneByText(getRoot(), "移出(") if (confirmButton != null) { AccessibilityUtil.performClick(confirmButton) } else { @@ -847,7 +891,7 @@ object WeworkOperationImpl { /** * 发送消息+@at */ - private fun sendChatMessage(text: String, prefix: String = "", at: String? = null) { + private fun sendChatMessage(text: String, at: String? = null, reply: Boolean? = false) { val voiceFlag = AccessibilityUtil.findOnceByText(getRoot(), "按住 说话", "按住说话", exact = true) if (voiceFlag != null) { AccessibilityUtil.performClickWithSon(AccessibilityUtil.findFrontNode(voiceFlag)) @@ -889,8 +933,8 @@ object WeworkOperationImpl { } } } - val content = if (atFailed) "@$at $prefix$text" else "$prefix$text" - val append = !at.isNullOrEmpty() && !atFailed + val content = if (atFailed) "@$at $text" else "$text" + val append = (reply == true) || (!at.isNullOrEmpty() && !atFailed) if (AccessibilityUtil.findTextInput(getRoot(), content, append = append)) { val sendButton = AccessibilityUtil.findAllByClazz(getRoot(), Views.Button) .firstOrNull { it.text == "发送" } diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkService.kt b/app/src/main/java/org/yameida/worktool/service/WeworkService.kt index ae56546..4f8eea6 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkService.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkService.kt @@ -5,17 +5,14 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter -import android.os.Build import android.util.Log import android.view.accessibility.AccessibilityEvent -import androidx.annotation.RequiresApi import com.blankj.utilcode.util.* import okhttp3.Response import okhttp3.WebSocket import okhttp3.WebSocketListener import org.yameida.worktool.Constant import org.yameida.worktool.Demo -import org.yameida.worktool.config.WebConfig import org.yameida.worktool.utils.* import java.lang.Exception @@ -31,9 +28,7 @@ class WeworkService : AccessibilityService() { override fun onServiceConnected() { LogUtils.i("初始化成功") //隐藏软键盘模式 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - softKeyboardController.showMode = SHOW_MODE_HIDDEN - } + softKeyboardController.showMode = SHOW_MODE_HIDDEN WeworkController.weworkService = this //初始化长连接 initWebSocket() @@ -51,12 +46,11 @@ class WeworkService : AccessibilityService() { initWebSocket() } } - }, IntentFilter(WebConfig.WEWORK_NOTIFY)) + }, IntentFilter(Constant.WEWORK_NOTIFY)) } private fun initWebSocket() { - val url = - WebConfig.WEWORK_URL + SPUtils.getInstance().getString(WebConfig.LISTEN_CHANNEL_ID) + val url = Constant.getWsUrl() val listener = EchoWebSocketListener() LogUtils.d("initWebSocket: $url") webSocketManager = WebSocketManager(url, listener) @@ -67,7 +61,6 @@ class WeworkService : AccessibilityService() { * TYPE_VIEW_SCROLLED 列表滚动 * @param event */ - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) override fun onAccessibilityEvent(event: AccessibilityEvent) { } @@ -79,9 +72,7 @@ class WeworkService : AccessibilityService() { super.onDestroy() LogUtils.i("onDestroy") //隐藏软键盘模式 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - softKeyboardController.showMode = SHOW_MODE_AUTO - } + softKeyboardController.showMode = SHOW_MODE_AUTO webSocketManager.close(1000, "service Destroy") } @@ -91,7 +82,7 @@ class WeworkService : AccessibilityService() { override fun onOpen(webSocket: WebSocket, response: Response) { socket = webSocket Log.e(TAG, "链接建立") - val robotId = SPUtils.getInstance().getString(WebConfig.LISTEN_CHANNEL_ID, "") + val robotId = SPUtils.getInstance().getString(Constant.LISTEN_CHANNEL_ID, "") val appVersion = SPUtils.getInstance().getString("appVersion", "") val workVersion= SPUtils.getInstance().getString("workVersion", "") log("链接建立: $robotId appVersion: $appVersion workVersion: $workVersion") 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 6532dd9..c3a8f4a 100644 --- a/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt +++ b/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt @@ -4,13 +4,11 @@ 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 import android.view.accessibility.AccessibilityEvent @@ -19,7 +17,6 @@ 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 import com.blankj.utilcode.util.ScreenUtils import org.yameida.worktool.service.WeworkController @@ -56,8 +53,8 @@ import org.yameida.worktool.service.WeworkController */ object AccessibilityUtil { private const val tag = "AccessibilityUtil" - private const val SHORT_INTERVAL = 100L - private const val SCROLL_INTERVAL = 300L + private const val SHORT_INTERVAL = 150L + private const val SCROLL_INTERVAL = 500L //编辑EditView(非粘贴 推荐) fun editTextInput(nodeInfo: AccessibilityNodeInfo?, text: String): Boolean { @@ -154,7 +151,6 @@ object AccessibilityUtil { } //输入x, y坐标模拟点击事件 - @TargetApi(Build.VERSION_CODES.N) fun performXYClick(service: AccessibilityService, x: Float, y: Float): Boolean { val path = Path() path.moveTo(x, y) @@ -175,16 +171,23 @@ object AccessibilityUtil { /** * 对某个节点或父节点进行点击 */ - fun performClick(nodeInfo: AccessibilityNodeInfo?): Boolean { - var nodeInfo: AccessibilityNodeInfo? = nodeInfo ?: return false - while (nodeInfo != null) { - if (nodeInfo.isClickable) { - nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK) + fun performClick(nodeInfo: AccessibilityNodeInfo?, retry: Boolean = true): Boolean { + var tempNodeInfo: AccessibilityNodeInfo? = nodeInfo ?: return false + while (tempNodeInfo != null) { + if (tempNodeInfo.isClickable) { + tempNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK) + LogUtils.v("performClick success! ${nodeInfo.className}") return true } - nodeInfo = nodeInfo.parent + tempNodeInfo = tempNodeInfo.parent + } + LogUtils.e("performClick failed! retry: $retry ${nodeInfo.className}") + if (retry) { + sleep(SHORT_INTERVAL * 2) + nodeInfo.refresh() + val click = clickByNode(WeworkController.weworkService, nodeInfo) + LogUtils.e("performClick failed! clickByNode: $click") } - LogUtils.e("performClick failed! ${nodeInfo?.className}") return false } @@ -380,6 +383,54 @@ object AccessibilityUtil { return null } + /** + * 按正则表达式寻找节点和子节点内的一个匹配项 + * @param node 节点 + * @param regex 表达式 + * @param timeout 检查超时时间 + */ + fun findOneByTextRegex( + node: AccessibilityNodeInfo?, + regex: String, + timeout: Long = 5000, + root: Boolean = true + ): AccessibilityNodeInfo? { + var node = node ?: return null + val startTime = System.currentTimeMillis() + var currentTime = startTime + while (currentTime - startTime <= timeout) { + val result = findOnceByTextRegex(node, regex) + if (result != null) return result + sleep(SHORT_INTERVAL) + if (root) { + node = getRoot(true) + } else { + node.refresh() + } + currentTime = System.currentTimeMillis() + } + Log.e(tag, "findOneByTextRegex: not found: $regex") + return null + } + + /** + * 按正则表达式寻找节点和子节点内的一个匹配项 + * @param node 节点 + * @param regex 表达式 + */ + fun findOnceByTextRegex( + node: AccessibilityNodeInfo?, + regex: String + ): AccessibilityNodeInfo? { + if (node == null) return null + val textNodeList = findAllOnceByTextRegex(node, regex) + LogUtils.v("regex: $regex count: " + textNodeList.size) + if (textNodeList.size > 0) { + return textNodeList[0] + } + return null + } + /** * 按文本(关键词)寻找节点和子节点内的一个匹配项 * @param node 节点 @@ -495,6 +546,60 @@ object AccessibilityUtil { return list } + /** + * 按正则表达式寻找节点和子节点内的所有匹配项 + * @param node 节点 + * @param regex 关键词 + * @param timeout 检查超时时间 + */ + fun findAllByTextRegex( + node: AccessibilityNodeInfo?, + regex: String, + timeout: Long = 5000, + root: Boolean = true, + minSize: Int = 1 + ): List { + var node = node ?: return arrayListOf() + val startTime = System.currentTimeMillis() + var currentTime = startTime + while (currentTime - startTime <= timeout) { + val result = findAllOnceByTextRegex(node, regex) + LogUtils.v("regex: $regex count: " + result.size) + if (result.size >= minSize) return result + sleep(SHORT_INTERVAL) + if (root) { + node = getRoot(true) + } else { + node.refresh() + } + currentTime = System.currentTimeMillis() + } + Log.e(tag, "findAllByTextRegex: not found: $regex") + return arrayListOf() + } + + /** + * 按正则表达式寻找节点和子节点内的所有匹配项 + * node 节点 + * clazz 类名 + * limitDepth 深度 限制深度搜索深度必须匹配提供值且类名相同才返回 不填默认不限制 + */ + fun findAllOnceByTextRegex( + node: AccessibilityNodeInfo?, + regex: String, + list: ArrayList = ArrayList() + ): ArrayList { + if (node == null) return list + val nodeText = node.text?.toString() + if (nodeText != null && nodeText.matches(regex.toRegex())) { + list.add(node) + } + for (i in 0 until node.childCount) { + findAllOnceByTextRegex(node.getChild(i), regex, list = list) + } + return list + } + /** * 按类名寻找节点和子节点内的一个匹配项 * node 节点 @@ -509,13 +614,14 @@ object AccessibilityUtil { depth: Int = 0, timeout: Long = 5000, root: Boolean = true, - minChildCount: Int = 0 + minChildCount: Int = 0, + firstChildClazz: String? = null ): AccessibilityNodeInfo? { var node = node ?: return null val startTime = System.currentTimeMillis() var currentTime = startTime while (currentTime - startTime <= timeout) { - val result = findOnceByClazz(node, *clazzList, limitDepth = limitDepth, depth = depth, minChildCount = minChildCount) + val result = findOnceByClazz(node, *clazzList, limitDepth = limitDepth, depth = depth, minChildCount = minChildCount, firstChildClazz = firstChildClazz) LogUtils.v("clazz: ${clazzList.joinToString()} result == null: ${result == null}") if (result != null) return result sleep(SHORT_INTERVAL) @@ -542,15 +648,18 @@ object AccessibilityUtil { vararg clazzList: String, limitDepth: Int? = null, depth: Int = 0, - minChildCount: Int = 0 + minChildCount: Int = 0, + firstChildClazz: String? = null ): AccessibilityNodeInfo? { if (node == null) return null if (node.className in clazzList) { if ((limitDepth == null || limitDepth == depth) && node.childCount >= minChildCount) - return node + if (firstChildClazz == null || (node.childCount > 0 && firstChildClazz == node.getChild(0).className)) { + return node + } } for (i in 0 until node.childCount) { - val result = findOnceByClazz(node.getChild(i), *clazzList, limitDepth = limitDepth, depth = depth + 1, minChildCount = minChildCount) + val result = findOnceByClazz(node.getChild(i), *clazzList, limitDepth = limitDepth, depth = depth + 1, minChildCount = minChildCount, firstChildClazz = firstChildClazz) if (result != null) return result } return null @@ -696,7 +805,7 @@ object AccessibilityUtil { for (i in 0 until depth) { s += "---" } - Log.d(tag, "$s depth: $depth className: " + node.className) + Log.d(tag, "$s depth: $depth className: " + node.className + " isClickable: " + node.isClickable) if (printText && node.text != null) { Log.d(tag, "$s depth: $depth text: " + node.text) } @@ -712,11 +821,11 @@ object AccessibilityUtil { * Gesture手势实现点击(Android7+) * 解决 clickable=false 无法点击问题 */ - @RequiresApi(api = Build.VERSION_CODES.N) fun clickByNode( service: AccessibilityService, nodeInfo: AccessibilityNodeInfo ): Boolean { + nodeInfo.refresh() val rect = Rect() nodeInfo.getBoundsInScreen(rect) val x: Int = (rect.left + rect.right) / 2 @@ -743,7 +852,6 @@ object AccessibilityUtil { * Gesture手势实现滚动(Android7+) * 解决 scrollable=false 无法滚动问题 */ - @RequiresApi(api = Build.VERSION_CODES.N) fun scrollDownByNode( service: AccessibilityService, nodeInfo: AccessibilityNodeInfo @@ -781,29 +889,24 @@ object AccessibilityUtil { distanceX: Int = 0, distanceY: Int = 0 ): Boolean { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - val rect = Rect() - nodeInfo.getBoundsInScreen(rect) - val point = Point((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2) - val builder = GestureDescription.Builder() - val path = Path() - path.moveTo(point.x.toFloat(), point.y.toFloat()) - path.lineTo(point.x.toFloat() + distanceX, point.y.toFloat() + distanceY) - builder.addStroke(StrokeDescription(path, 0L, 300L)) - val gesture = builder.build() - return service.dispatchGesture(gesture, object : GestureResultCallback() { - override fun onCompleted(gestureDescription: GestureDescription) { - LogUtils.v("scroll ok onCompleted") - } + val rect = Rect() + nodeInfo.getBoundsInScreen(rect) + val point = Point((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2) + val builder = GestureDescription.Builder() + val path = Path() + path.moveTo(point.x.toFloat(), point.y.toFloat()) + path.lineTo(point.x.toFloat() + distanceX, point.y.toFloat() + distanceY) + builder.addStroke(StrokeDescription(path, 0L, 300L)) + val gesture = builder.build() + return service.dispatchGesture(gesture, object : GestureResultCallback() { + override fun onCompleted(gestureDescription: GestureDescription) { + LogUtils.v("scroll ok onCompleted") + } - override fun onCancelled(gestureDescription: GestureDescription) { - LogUtils.v("scroll ok onCancelled") - } - }, null) - } else { - LogUtils.e("系统版本<7.0 不支持手势操作") - return false - } + override fun onCancelled(gestureDescription: GestureDescription) { + LogUtils.v("scroll ok onCancelled") + } + }, null) } /** @@ -819,25 +922,20 @@ object AccessibilityUtil { distanceX: Int = 0, distanceY: Int = 0 ): Boolean { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - val builder = GestureDescription.Builder() - val path = Path() - path.moveTo(x.toFloat(), y.toFloat()) - path.lineTo(x.toFloat() + distanceX, y.toFloat() + distanceY) - builder.addStroke(StrokeDescription(path, 0L, 300L)) - val gesture = builder.build() - return service.dispatchGesture(gesture, object : GestureResultCallback() { - override fun onCompleted(gestureDescription: GestureDescription) { - LogUtils.v("scroll ok onCompleted") - } + val builder = GestureDescription.Builder() + val path = Path() + path.moveTo(x.toFloat(), y.toFloat()) + path.lineTo(x.toFloat() + distanceX, y.toFloat() + distanceY) + builder.addStroke(StrokeDescription(path, 0L, 300L)) + val gesture = builder.build() + return service.dispatchGesture(gesture, object : GestureResultCallback() { + override fun onCompleted(gestureDescription: GestureDescription) { + LogUtils.v("scroll ok onCompleted") + } - override fun onCancelled(gestureDescription: GestureDescription) { - LogUtils.v("scroll ok onCancelled") - } - }, null) - } else { - LogUtils.e("系统版本<7.0 不支持手势操作") - return false - } + override fun onCancelled(gestureDescription: GestureDescription) { + LogUtils.v("scroll ok onCancelled") + } + }, null) } } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/UpdateUtil.kt b/app/src/main/java/org/yameida/worktool/utils/UpdateUtil.kt index 39512a9..53c6ed1 100644 --- a/app/src/main/java/org/yameida/worktool/utils/UpdateUtil.kt +++ b/app/src/main/java/org/yameida/worktool/utils/UpdateUtil.kt @@ -16,7 +16,7 @@ import update.UpdateAppUtils object UpdateUtil { fun checkUpdate() { - OkGo.get(Constant.URL_CHECK_UPDATE) + OkGo.get(Constant.getCheckUpdateUrl()) .execute(object : StringCallback() { override fun onSuccess(response: Response) { val commonResult = 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 88779cb..9f9e32e 100644 --- a/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt +++ b/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt @@ -6,10 +6,7 @@ import org.yameida.worktool.utils.AccessibilityUtil.findFrontNode import org.yameida.worktool.model.WeworkMessageBean import com.blankj.utilcode.util.LogUtils import org.yameida.worktool.Constant -import org.yameida.worktool.service.backPress -import org.yameida.worktool.service.getRoot -import org.yameida.worktool.service.goHome -import org.yameida.worktool.service.sleep +import org.yameida.worktool.service.* import org.yameida.worktool.utils.AccessibilityUtil.findAllOnceByClazz /** @@ -101,13 +98,21 @@ object WeworkRoomUtil { val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 2] val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1] AccessibilityUtil.performClick(searchButton) - AccessibilityUtil.findTextInput(getRoot(), title.replace("…", "").replace("-.*$".toRegex(), "")) + val needTrim = title.contains(Constant.regTrimTitle) + val trimTitle = title.replace(Constant.regTrimTitle, "") + AccessibilityUtil.findTextInput(getRoot(), trimTitle) sleep(Constant.CHANGE_PAGE_INTERVAL) //消息页搜索结果列表 val selectListView = findOneByClazz(getRoot(), Views.ListView) - val imageView = AccessibilityUtil.findOnceByClazz(selectListView, Views.ImageView) - if (imageView != null) { - AccessibilityUtil.performClick(imageView) + val searchResult = AccessibilityUtil.findOneByText( + selectListView, + trimTitle, + exact = !needTrim, + timeout = 2000, + root = false + ) + if (searchResult != null) { + AccessibilityUtil.performClick(searchResult) LogUtils.d("进入房间: $title") sleep(Constant.CHANGE_PAGE_INTERVAL) return true diff --git a/app/src/main/res/layout/dialog_input.xml b/app/src/main/res/layout/dialog_input.xml new file mode 100644 index 0000000..4eabb88 --- /dev/null +++ b/app/src/main/res/layout/dialog_input.xml @@ -0,0 +1,37 @@ + + + + + + + +