update 图片截图
This commit is contained in:
@@ -243,6 +243,9 @@ public class WeworkMessageBean {
|
|||||||
public Integer textType;
|
public Integer textType;
|
||||||
public List<ItemMessageBean> itemMessageList;
|
public List<ItemMessageBean> itemMessageList;
|
||||||
public List<String> nameList;
|
public List<String> nameList;
|
||||||
|
public Boolean imageRepeat;
|
||||||
|
public Integer imageSize;
|
||||||
|
public byte[] image;
|
||||||
|
|
||||||
public SubMessageBean(Integer sender, Integer textType, List<ItemMessageBean> itemMessageList, List<String> nameList) {
|
public SubMessageBean(Integer sender, Integer textType, List<ItemMessageBean> itemMessageList, List<String> nameList) {
|
||||||
this.sender = sender;
|
this.sender = sender;
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ object MyLooper {
|
|||||||
SPUtils.getInstance("noSyncMessage").clear()
|
SPUtils.getInstance("noSyncMessage").clear()
|
||||||
SPUtils.getInstance("limit").clear()
|
SPUtils.getInstance("limit").clear()
|
||||||
SPUtils.getInstance("groupInvite").clear()
|
SPUtils.getInstance("groupInvite").clear()
|
||||||
|
SPUtils.getInstance("lastImage").clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getInstance(): Handler {
|
fun getInstance(): Handler {
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package org.yameida.worktool.service
|
package org.yameida.worktool.service
|
||||||
|
|
||||||
|
import android.os.Message
|
||||||
import android.view.accessibility.AccessibilityNodeInfo
|
import android.view.accessibility.AccessibilityNodeInfo
|
||||||
import androidx.core.text.isDigitsOnly
|
import androidx.core.text.isDigitsOnly
|
||||||
import com.blankj.utilcode.util.*
|
import com.blankj.utilcode.util.*
|
||||||
import org.yameida.worktool.Constant
|
import org.yameida.worktool.Constant
|
||||||
import org.yameida.worktool.Demo
|
import org.yameida.worktool.Demo
|
||||||
|
import org.yameida.worktool.activity.GetScreenShotActivity
|
||||||
import org.yameida.worktool.model.WeworkMessageBean
|
import org.yameida.worktool.model.WeworkMessageBean
|
||||||
import org.yameida.worktool.observer.MultiFileObserver
|
import org.yameida.worktool.observer.MultiFileObserver
|
||||||
import org.yameida.worktool.service.WeworkController.mainLoopRunning
|
import org.yameida.worktool.service.WeworkController.mainLoopRunning
|
||||||
@@ -15,6 +17,7 @@ import java.lang.StringBuilder
|
|||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
import kotlin.collections.LinkedHashSet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取数据类型 201 202 主循环
|
* 获取数据类型 201 202 主循环
|
||||||
@@ -46,7 +49,13 @@ object WeworkLoopImpl {
|
|||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
mainLoopRunning = false
|
mainLoopRunning = false
|
||||||
error("ERROR mainLoop: " + e.message)
|
LogUtils.e("ERROR mainLoop: " + e.message, e)
|
||||||
|
error("ERROR mainLoop: $e")
|
||||||
|
sleep(Constant.LONG_INTERVAL)
|
||||||
|
MyLooper.getInstance().sendMessage(Message.obtain().apply {
|
||||||
|
what = WeworkMessageBean.LOOP_RECEIVE_NEW_MESSAGE
|
||||||
|
obj = WeworkMessageBean().apply { type = WeworkMessageBean.LOOP_RECEIVE_NEW_MESSAGE }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,15 +136,18 @@ object WeworkLoopImpl {
|
|||||||
log("聊天: $title")
|
log("聊天: $title")
|
||||||
val messageList = arrayListOf<WeworkMessageBean.SubMessageBean>()
|
val messageList = arrayListOf<WeworkMessageBean.SubMessageBean>()
|
||||||
val messageList2 = arrayListOf<WeworkMessageBean.SubMessageBean>()
|
val messageList2 = arrayListOf<WeworkMessageBean.SubMessageBean>()
|
||||||
|
val imageSet = LinkedHashSet<ByteArray>()
|
||||||
do {
|
do {
|
||||||
messageList.clear()
|
messageList.clear()
|
||||||
messageList2.clear()
|
messageList2.clear()
|
||||||
|
imageSet.clear()
|
||||||
//聊天消息列表 1ListView 0RecycleView xViewGroup
|
//聊天消息列表 1ListView 0RecycleView xViewGroup
|
||||||
val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
|
val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
LogUtils.v("消息条数: " + list.childCount)
|
val childCount = list.childCount
|
||||||
|
LogUtils.v("消息条数: $childCount")
|
||||||
for (i in 0 until list.childCount) {
|
for (i in 0 until list.childCount) {
|
||||||
val item = list.getChild(i)
|
val item = list.getChild(childCount - 1 - i)
|
||||||
if (item != null && item.childCount > 0) {
|
if (item != null && item.childCount > 0) {
|
||||||
messageList.add(parseChatMessageItem(item, titleList, roomType, false))
|
messageList.add(parseChatMessageItem(item, titleList, roomType, false))
|
||||||
}
|
}
|
||||||
@@ -145,10 +157,29 @@ object WeworkLoopImpl {
|
|||||||
LogUtils.v("双重校验聊天列表")
|
LogUtils.v("双重校验聊天列表")
|
||||||
val list2 = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
|
val list2 = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
|
||||||
if (list2 != null) {
|
if (list2 != null) {
|
||||||
LogUtils.v("list2消息条数: " + list2.childCount)
|
val childCount = list2.childCount
|
||||||
|
LogUtils.v("list2消息条数: $childCount")
|
||||||
var imageCheck = true
|
var imageCheck = true
|
||||||
|
if (Constant.enableMediaProject) {
|
||||||
|
for (i in 0 until childCount) {
|
||||||
|
val item = list2.getChild(childCount - 1 - i)
|
||||||
|
if (item != null && item.childCount > 0) {
|
||||||
|
val chatMessageItem = parseChatMessageItem(item, titleList, roomType, imageCheck)
|
||||||
|
if (chatMessageItem.imageRepeat == true) {
|
||||||
|
chatMessageItem.imageRepeat = null
|
||||||
|
imageCheck = false
|
||||||
|
}
|
||||||
|
if (chatMessageItem.image != null) {
|
||||||
|
imageSet.add(chatMessageItem.image)
|
||||||
|
chatMessageItem.image = null
|
||||||
|
chatMessageItem.imageSize = null
|
||||||
|
}
|
||||||
|
messageList2.add(chatMessageItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for (i in 0 until list2.childCount) {
|
for (i in 0 until list2.childCount) {
|
||||||
val item = list2.getChild(i)
|
val item = list2.getChild(childCount - 1 - i)
|
||||||
if (item != null && item.childCount > 0) {
|
if (item != null && item.childCount > 0) {
|
||||||
val chatMessageItem = parseChatMessageItem(item, titleList, roomType, imageCheck)
|
val chatMessageItem = parseChatMessageItem(item, titleList, roomType, imageCheck)
|
||||||
if (chatMessageItem.sender == 0 && chatMessageItem.textType == WeworkMessageBean.TEXT_TYPE_IMAGE) {
|
if (chatMessageItem.sender == 0 && chatMessageItem.textType == WeworkMessageBean.TEXT_TYPE_IMAGE) {
|
||||||
@@ -158,11 +189,13 @@ object WeworkLoopImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (messageList != messageList2) {
|
if (messageList != messageList2) {
|
||||||
LogUtils.e("双重校验聊天列表失败")
|
LogUtils.e("双重校验聊天列表失败")
|
||||||
}
|
}
|
||||||
} while (messageList != messageList2)
|
} while (messageList != messageList2)
|
||||||
if (messageList.isNotEmpty()) {
|
if (messageList.isNotEmpty()) {
|
||||||
|
messageList.reverse()
|
||||||
val lastMessage = messageList.last()
|
val lastMessage = messageList.last()
|
||||||
val prefix = (lastMessage.nameList.firstOrNull()?.replace("\\(.*\\)$".toRegex(), "") + ": ").replace("null:", "")
|
val prefix = (lastMessage.nameList.firstOrNull()?.replace("\\(.*\\)$".toRegex(), "") + ": ").replace("null:", "")
|
||||||
val lastSyncMessage = prefix + if (lastMessage.textType == WeworkMessageBean.TEXT_TYPE_IMAGE) {
|
val lastSyncMessage = prefix + if (lastMessage.textType == WeworkMessageBean.TEXT_TYPE_IMAGE) {
|
||||||
@@ -172,7 +205,24 @@ object WeworkLoopImpl {
|
|||||||
}
|
}
|
||||||
SPUtils.getInstance("lastSyncMessage").put(title, lastSyncMessage)
|
SPUtils.getInstance("lastSyncMessage").put(title, lastSyncMessage)
|
||||||
LogUtils.v("lastSyncMessage: $lastSyncMessage")
|
LogUtils.v("lastSyncMessage: $lastSyncMessage")
|
||||||
if (Constant.pushImage) {
|
if (Constant.enableMediaProject && Constant.pushImage) {
|
||||||
|
log("image: ${imageSet.size}")
|
||||||
|
if (imageSet.isNotEmpty()) {
|
||||||
|
val imageMessageList = messageList.filter { it.textType == WeworkMessageBean.TEXT_TYPE_IMAGE }.reversed()
|
||||||
|
LogUtils.v("lastImage: ${imageSet.first().size}")
|
||||||
|
SPUtils.getInstance("lastImage").put(titleList.joinToString(), imageSet.first().size)
|
||||||
|
imageSet.reversed().forEachIndexed { index, bytes ->
|
||||||
|
if (imageMessageList.size > index) {
|
||||||
|
val message = imageMessageList[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (subMessageBean in messageList) {
|
||||||
|
subMessageBean.image = null
|
||||||
|
subMessageBean.imageSize = null
|
||||||
|
subMessageBean.imageRepeat = null
|
||||||
|
}
|
||||||
|
} else if (!Constant.enableMediaProject && Constant.pushImage) {
|
||||||
log("createSet: ${MultiFileObserver.createSet.joinToString()}\nsaveSet: ${MultiFileObserver.saveSet.joinToString()}")
|
log("createSet: ${MultiFileObserver.createSet.joinToString()}\nsaveSet: ${MultiFileObserver.saveSet.joinToString()}")
|
||||||
if (MultiFileObserver.saveSet.isNotEmpty()) {
|
if (MultiFileObserver.saveSet.isNotEmpty()) {
|
||||||
val imageMessageList = messageList.filter { it.textType == WeworkMessageBean.TEXT_TYPE_IMAGE }.reversed()
|
val imageMessageList = messageList.filter { it.textType == WeworkMessageBean.TEXT_TYPE_IMAGE }.reversed()
|
||||||
@@ -595,6 +645,44 @@ object WeworkLoopImpl {
|
|||||||
message = WeworkMessageBean.SubMessageBean(0, textType, itemMessageList, nameList)
|
message = WeworkMessageBean.SubMessageBean(0, textType, itemMessageList, nameList)
|
||||||
//图片类型特殊处理
|
//图片类型特殊处理
|
||||||
if (imageCheck && Constant.pushImage && textType == WeworkMessageBean.TEXT_TYPE_IMAGE) {
|
if (imageCheck && Constant.pushImage && textType == WeworkMessageBean.TEXT_TYPE_IMAGE) {
|
||||||
|
if (Constant.enableMediaProject) {
|
||||||
|
AccessibilityUtil.performClickWithSon(relativeLayoutContent)
|
||||||
|
AccessibilityExtraUtil.loadingPage("ShowImageController", Constant.CHANGE_PAGE_INTERVAL)
|
||||||
|
//图片双重校验
|
||||||
|
var image = 0
|
||||||
|
var image2 = 0
|
||||||
|
var byte: ByteArray? = null
|
||||||
|
do {
|
||||||
|
val bitmap = GetScreenShotActivity.startCapture()
|
||||||
|
byte = ImageUtils.bitmap2Bytes(bitmap)
|
||||||
|
LogUtils.v("bitmap byte: ${byte.size}")
|
||||||
|
image = byte.size
|
||||||
|
sleep(Constant.POP_WINDOW_INTERVAL / 2)
|
||||||
|
val bitmap2 = GetScreenShotActivity.startCapture()
|
||||||
|
val byte2 = ImageUtils.bitmap2Bytes(bitmap2)
|
||||||
|
LogUtils.v("bitmap2 byte: ${byte2.size}")
|
||||||
|
image2 = byte2.size
|
||||||
|
if (image != image2) {
|
||||||
|
LogUtils.e("图片双重校验失败")
|
||||||
|
}
|
||||||
|
} while (image != image2)
|
||||||
|
if (byte != null) {
|
||||||
|
if (titleList.isNotEmpty()) {
|
||||||
|
val lastImage = SPUtils.getInstance("lastImage").getInt(titleList.joinToString())
|
||||||
|
if (lastImage == byte.size) {
|
||||||
|
message.imageRepeat = true
|
||||||
|
} else {
|
||||||
|
message.imageSize = byte.size
|
||||||
|
message.image = byte
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var retry = 3
|
||||||
|
while (retry-- > 0 && WeworkController.weworkService.currentClass == "com.tencent.wework.msg.controller.ShowImageController") {
|
||||||
|
AccessibilityUtil.performXYClick(WeworkController.weworkService, ScreenUtils.getScreenWidth() / 2F, BarUtils.getStatusBarHeight() * 2F)
|
||||||
|
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
MultiFileObserver.createSet.clear()
|
MultiFileObserver.createSet.clear()
|
||||||
MultiFileObserver.finishSet.clear()
|
MultiFileObserver.finishSet.clear()
|
||||||
MultiFileObserver.saveSet.clear()
|
MultiFileObserver.saveSet.clear()
|
||||||
@@ -647,6 +735,7 @@ object WeworkLoopImpl {
|
|||||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (Views.ImageView.equals(relativeLayoutItem.getChild(1).className)) {
|
} else if (Views.ImageView.equals(relativeLayoutItem.getChild(1).className)) {
|
||||||
LogUtils.v("头像在右边 本条消息发送者为自己")
|
LogUtils.v("头像在右边 本条消息发送者为自己")
|
||||||
var textType = WeworkMessageBean.TEXT_TYPE_UNKNOWN
|
var textType = WeworkMessageBean.TEXT_TYPE_UNKNOWN
|
||||||
|
|||||||
@@ -1264,4 +1264,59 @@ object AccessibilityUtil {
|
|||||||
sleep(SCROLL_INTERVAL)
|
sleep(SCROLL_INTERVAL)
|
||||||
return dispatchGesture
|
return dispatchGesture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 等待文案消失
|
||||||
|
*/
|
||||||
|
fun waitForTextMissing(
|
||||||
|
node: AccessibilityNodeInfo?,
|
||||||
|
vararg textList: String,
|
||||||
|
exact: Boolean = false,
|
||||||
|
timeout: Long = 5000,
|
||||||
|
root: Boolean = true,
|
||||||
|
desc: Boolean = false
|
||||||
|
): Boolean {
|
||||||
|
var node = node ?: return true
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
var currentTime = startTime
|
||||||
|
while (currentTime - startTime <= timeout) {
|
||||||
|
findOnceByText(node, *textList, exact = exact, desc = desc) ?: return true
|
||||||
|
sleep(SHORT_INTERVAL)
|
||||||
|
if (root) {
|
||||||
|
node = getRoot(true)
|
||||||
|
} else {
|
||||||
|
node.refresh()
|
||||||
|
}
|
||||||
|
currentTime = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
Log.e(tag, "waitForTextMissing ${if (desc) "desc" else "text"}: found: ${textList.joinToString()}")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 等待控件消失
|
||||||
|
*/
|
||||||
|
fun waitForClazzMissing(
|
||||||
|
node: AccessibilityNodeInfo?,
|
||||||
|
vararg clazzList: String,
|
||||||
|
timeout: Long = 5000,
|
||||||
|
root: Boolean = true
|
||||||
|
): Boolean {
|
||||||
|
var node = node ?: return true
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
var currentTime = startTime
|
||||||
|
while (currentTime - startTime <= timeout) {
|
||||||
|
findOnceByClazz(node, *clazzList) ?: return true
|
||||||
|
sleep(SHORT_INTERVAL)
|
||||||
|
if (root) {
|
||||||
|
node = getRoot(true)
|
||||||
|
} else {
|
||||||
|
node.refresh()
|
||||||
|
}
|
||||||
|
currentTime = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
LogUtils.e("waitForClazzMissing found: ${clazzList.joinToString()}")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ object HttpUtil {
|
|||||||
json.put("groupRemark", null)
|
json.put("groupRemark", null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
json.put("receivedName", titleList.lastOrNull() { !it.contains("@") } ?: "")
|
json.put("receivedName", titleList.lastOrNull { !it.contains("@") } ?: "")
|
||||||
json.put("groupName", null)
|
json.put("groupName", null)
|
||||||
json.put("groupRemark", null)
|
json.put("groupRemark", null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.blankj.utilcode.util.GsonUtils;
|
|||||||
import com.blankj.utilcode.util.LogUtils;
|
import com.blankj.utilcode.util.LogUtils;
|
||||||
import com.hjq.toast.ToastUtils;
|
import com.hjq.toast.ToastUtils;
|
||||||
|
|
||||||
|
import org.yameida.worktool.Constant;
|
||||||
import org.yameida.worktool.model.WeworkMessageBean;
|
import org.yameida.worktool.model.WeworkMessageBean;
|
||||||
import org.yameida.worktool.model.WeworkMessageListBean;
|
import org.yameida.worktool.model.WeworkMessageListBean;
|
||||||
import org.yameida.worktool.service.WeworkController;
|
import org.yameida.worktool.service.WeworkController;
|
||||||
@@ -157,9 +158,11 @@ public class WebSocketManager {
|
|||||||
//重连后刷新连接时间
|
//重连后刷新连接时间
|
||||||
lastConnectedTime = System.currentTimeMillis();
|
lastConnectedTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
if (!Constant.INSTANCE.getEnableMediaProject()) {
|
||||||
if (System.currentTimeMillis() - lastConnectedTime > heartBeatRate * 3000 && !FloatWindowHelper.INSTANCE.isPause()) {
|
if (System.currentTimeMillis() - lastConnectedTime > heartBeatRate * 3000 && !FloatWindowHelper.INSTANCE.isPause()) {
|
||||||
ToastUtils.show("机器人运行中 请勿人工操作手机~");
|
ToastUtils.show("机器人运行中 请勿人工操作手机~");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//每heartBeatRate秒发一次心跳包
|
//每heartBeatRate秒发一次心跳包
|
||||||
|
|||||||
Reference in New Issue
Block a user