Merge branch 'master' of https://github.com/gallonyin/worktool into master
This commit is contained in:
14
README.md
14
README.md
@@ -27,7 +27,7 @@ https://www.apifox.cn/apidoc/project-1035094/doc-840833
|
|||||||
2. 手机登录企业微信(账号需要提前实名认证,不然很多功能无法正常使用)
|
2. 手机登录企业微信(账号需要提前实名认证,不然很多功能无法正常使用)
|
||||||
3. 建议提前给该企业微信账号开通"工作台"-"客户群"权限(如无需外部群创建和管理可不开启)
|
3. 建议提前给该企业微信账号开通"工作台"-"客户群"权限(如无需外部群创建和管理可不开启)
|
||||||
4. 自助申请一个[机器人链接号(点击这里)](https://wt.asrtts.cn/regist.html),您也可以加入QQ群向管理员咨询如何操作。
|
4. 自助申请一个[机器人链接号(点击这里)](https://wt.asrtts.cn/regist.html),您也可以加入QQ群向管理员咨询如何操作。
|
||||||
5. 在这台手机上安装[WorkTool APP安装包(点击下载)](https://cdn.asrtts.cn/uploads/worktool/apk/worktool-2.5.4.apk)
|
5. 在这台手机上安装[WorkTool APP安装包(点击下载)](https://cdn.asrtts.cn/uploads/worktool/apk/worktool-2.5.6.apk)
|
||||||
6. 打开WorkTool APP,按照APP提示保存链接号,开启主功能,并打开到企业微信界面,不要关闭屏幕即可。
|
6. 打开WorkTool APP,按照APP提示保存链接号,开启主功能,并打开到企业微信界面,不要关闭屏幕即可。
|
||||||
|
|
||||||
如果您想使用自己开发的QA回调接口接收机器人收到的所有消息并定制回答,请参考[第三方QA回调接口规范(点击这里)](https://www.apifox.cn/apidoc/project-1035094/doc-861677)开发接口,并在[机器人第三方QA配置(点击这里)](https://www.apifox.cn/apidoc/project-1035094/api-22587884)提交您的机器人id和回调接口地址
|
如果您想使用自己开发的QA回调接口接收机器人收到的所有消息并定制回答,请参考[第三方QA回调接口规范(点击这里)](https://www.apifox.cn/apidoc/project-1035094/doc-861677)开发接口,并在[机器人第三方QA配置(点击这里)](https://www.apifox.cn/apidoc/project-1035094/api-22587884)提交您的机器人id和回调接口地址
|
||||||
@@ -59,13 +59,17 @@ Apache License, Version 2.0
|
|||||||
|
|
||||||
# 版本更新
|
# 版本更新
|
||||||
|
|
||||||
tag 2.5.4 2023-1-28 文件发送优化;消息列表识别优化;切换企业;其他已知缺陷修复
|
tag 2.5.6 2023-02-06 兼容主流模拟器;其他已知缺陷修复
|
||||||
|
|
||||||
tag 2.5.3 2023-1-11 群模板兼容新版;消息类型识别优化;其他已知缺陷修复
|
tag 2.5.5 2023-02-02 文件发送优化;新消息增强校验;其他已知缺陷修复
|
||||||
|
|
||||||
tag 2.5.2 2023-1-05 返回首页缺陷修复
|
tag 2.5.4 2023-01-28 文件发送优化;消息列表识别优化;切换企业;其他已知缺陷修复
|
||||||
|
|
||||||
tag 2.5.1 2023-1-04 优化返回首页和回复速度;支持群二维码回调;其他已知缺陷修复
|
tag 2.5.3 2023-01-11 群模板兼容新版;消息类型识别优化;其他已知缺陷修复
|
||||||
|
|
||||||
|
tag 2.5.2 2023-01-05 返回首页缺陷修复
|
||||||
|
|
||||||
|
tag 2.5.1 2023-01-04 优化返回首页和回复速度;支持群二维码回调;其他已知缺陷修复
|
||||||
|
|
||||||
tag 2.4.2 2022-12-14 优化at;优化通过好友请求;其他已知缺陷修复
|
tag 2.4.2 2022-12-14 优化at;优化通过好友请求;其他已知缺陷修复
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ android {
|
|||||||
applicationId "org.yameida.worktool"
|
applicationId "org.yameida.worktool"
|
||||||
minSdkVersion 24
|
minSdkVersion 24
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 2540
|
versionCode 2561
|
||||||
versionName "2.5.4"
|
versionName "2.5.6"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import com.blankj.utilcode.util.SPUtils
|
|||||||
|
|
||||||
object Constant {
|
object Constant {
|
||||||
|
|
||||||
val AVAILABLE_VERSION = arrayListOf("4.0.2", "4.0.6", "4.0.8", "4.0.10", "4.0.12", "4.0.16", "4.0.18", "4.0.19", "4.0.20")
|
val AVAILABLE_VERSION = arrayListOf("4.0.2", "4.0.6", "4.0.8", "4.0.10", "4.0.12", "4.0.16", "4.0.18", "4.0.19", "4.0.20", "4.1.0")
|
||||||
const val PACKAGE_NAMES = "com.tencent.wework"
|
const val PACKAGE_NAMES = "com.tencent.wework"
|
||||||
const val WEWORK_NOTIFY = "wework_notify"
|
const val WEWORK_NOTIFY = "wework_notify"
|
||||||
|
const val LONG_INTERVAL = 5000L
|
||||||
const val CHANGE_PAGE_INTERVAL = 1000L
|
const val CHANGE_PAGE_INTERVAL = 1000L
|
||||||
const val POP_WINDOW_INTERVAL = 500L
|
const val POP_WINDOW_INTERVAL = 500L
|
||||||
private const val DEFAULT_HOST = "wss://worktool.asrtts.cn"
|
private const val DEFAULT_HOST = "wss://worktool.asrtts.cn"
|
||||||
@@ -21,6 +22,8 @@ object Constant {
|
|||||||
var autoReply = SPUtils.getInstance().getInt("autoReply", 1)
|
var autoReply = SPUtils.getInstance().getInt("autoReply", 1)
|
||||||
var groupStrict = false
|
var groupStrict = false
|
||||||
var friendRemarkStrict = false
|
var friendRemarkStrict = false
|
||||||
|
var pushImage = false
|
||||||
|
var autoPublishComment = false
|
||||||
var robotId: String
|
var robotId: String
|
||||||
get() = SPUtils.getInstance().getString("robotId", SPUtils.getInstance().getString("LISTEN_CHANNEL_ID", ""))
|
get() = SPUtils.getInstance().getString("robotId", SPUtils.getInstance().getString("LISTEN_CHANNEL_ID", ""))
|
||||||
set(value) {
|
set(value) {
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ import com.umeng.analytics.MobclickAgent
|
|||||||
import kotlinx.android.synthetic.main.activity_listen.*
|
import kotlinx.android.synthetic.main.activity_listen.*
|
||||||
import org.yameida.worktool.*
|
import org.yameida.worktool.*
|
||||||
import android.content.*
|
import android.content.*
|
||||||
|
import android.os.FileObserver
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
|
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
|
||||||
|
import org.yameida.worktool.observer.MultiFileObserver
|
||||||
import org.yameida.worktool.utils.*
|
import org.yameida.worktool.utils.*
|
||||||
import org.yameida.worktool.utils.envcheck.CheckHook
|
import org.yameida.worktool.utils.envcheck.CheckHook
|
||||||
import org.yameida.worktool.utils.envcheck.CheckRoot
|
import org.yameida.worktool.utils.envcheck.CheckRoot
|
||||||
@@ -20,6 +22,8 @@ import org.yameida.worktool.utils.envcheck.CheckRoot
|
|||||||
|
|
||||||
class ListenActivity : AppCompatActivity() {
|
class ListenActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private var mFileObserver: FileObserver? = null
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* @param type 0=游客登录
|
* @param type 0=游客登录
|
||||||
@@ -42,6 +46,7 @@ class ListenActivity : AppCompatActivity() {
|
|||||||
initView()
|
initView()
|
||||||
initAccessibility()
|
initAccessibility()
|
||||||
initOverlays()
|
initOverlays()
|
||||||
|
initObserver()
|
||||||
initData()
|
initData()
|
||||||
PermissionUtils.permission("android.permission.READ_EXTERNAL_STORAGE").request()
|
PermissionUtils.permission("android.permission.READ_EXTERNAL_STORAGE").request()
|
||||||
registerReceiver(openWsReceiver, IntentFilter(Constant.WEWORK_NOTIFY))
|
registerReceiver(openWsReceiver, IntentFilter(Constant.WEWORK_NOTIFY))
|
||||||
@@ -155,6 +160,14 @@ class ListenActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initObserver() {
|
||||||
|
if (mFileObserver == null) {
|
||||||
|
mFileObserver =
|
||||||
|
MultiFileObserver("/storage/emulated/0/Android/data/com.tencent.wework/files/imagecache/imagemsg2");
|
||||||
|
mFileObserver?.startWatching()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun initData() {
|
private fun initData() {
|
||||||
HttpUtil.checkUpdate()
|
HttpUtil.checkUpdate()
|
||||||
HttpUtil.getMyConfig(toast = false)
|
HttpUtil.getMyConfig(toast = false)
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ public class WeworkMessageBean {
|
|||||||
public String extraText;
|
public String extraText;
|
||||||
//接收消息类型
|
//接收消息类型
|
||||||
public Integer textType;
|
public Integer textType;
|
||||||
|
//最大尝试次数
|
||||||
|
public Integer maxRetryCount;
|
||||||
|
|
||||||
//群名
|
//群名
|
||||||
public String groupName;
|
public String groupName;
|
||||||
|
|||||||
@@ -0,0 +1,152 @@
|
|||||||
|
package org.yameida.worktool.observer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import android.os.FileObserver;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class MultiFileObserver extends FileObserver {
|
||||||
|
|
||||||
|
public HashMap<String, Long> map = new HashMap<>();
|
||||||
|
public static String lastPicPath = "";
|
||||||
|
public static Long lastPicCreateTime = 0L;
|
||||||
|
|
||||||
|
/** Only modification events */
|
||||||
|
public static int CHANGES_ONLY = CREATE | MODIFY | DELETE | CLOSE_WRITE
|
||||||
|
| DELETE_SELF | MOVE_SELF | MOVED_FROM | MOVED_TO;
|
||||||
|
|
||||||
|
private List<SingleFileObserver> mObservers;
|
||||||
|
private String mPath;
|
||||||
|
private int mMask;
|
||||||
|
|
||||||
|
public MultiFileObserver(String path) {
|
||||||
|
this(path, ALL_EVENTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultiFileObserver(String path, int mask) {
|
||||||
|
super(path, mask);
|
||||||
|
mPath = path;
|
||||||
|
mMask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startWatching() {
|
||||||
|
if (mObservers != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mObservers = new ArrayList<SingleFileObserver>();
|
||||||
|
Stack<String> stack = new Stack<String>();
|
||||||
|
stack.push(mPath);
|
||||||
|
|
||||||
|
while (!stack.isEmpty()) {
|
||||||
|
String parent = stack.pop();
|
||||||
|
mObservers.add(new SingleFileObserver(parent, mMask));
|
||||||
|
File path = new File(parent);
|
||||||
|
File[] files = path.listFiles();
|
||||||
|
if (null == files)
|
||||||
|
continue;
|
||||||
|
for (File f : files) {
|
||||||
|
if (f.isDirectory() && !f.getName().equals(".")
|
||||||
|
&& !f.getName().equals("..")) {
|
||||||
|
stack.push(f.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mObservers.size(); i++) {
|
||||||
|
SingleFileObserver sfo = mObservers.get(i);
|
||||||
|
sfo.startWatching();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopWatching() {
|
||||||
|
if (mObservers == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < mObservers.size(); i++) {
|
||||||
|
SingleFileObserver sfo = mObservers.get(i);
|
||||||
|
sfo.stopWatching();
|
||||||
|
}
|
||||||
|
|
||||||
|
mObservers.clear();
|
||||||
|
mObservers = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEvent(int event, String path) {
|
||||||
|
switch (event) {
|
||||||
|
case FileObserver.ACCESS:
|
||||||
|
case FileObserver.CLOSE_NOWRITE:
|
||||||
|
if (path.endsWith(".0") && !map.containsKey(path)) {
|
||||||
|
Log.i("RecursiveFileObserver", "发现新图片: " + path);
|
||||||
|
map.put(path, System.currentTimeMillis());
|
||||||
|
lastPicPath = path;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FileObserver.CREATE:
|
||||||
|
Log.i("RecursiveFileObserver", "CREATE: " + path);
|
||||||
|
lastPicCreateTime = System.currentTimeMillis();
|
||||||
|
break;
|
||||||
|
case FileObserver.ATTRIB:
|
||||||
|
// Log.i("RecursiveFileObserver", "ATTRIB: " + path);
|
||||||
|
break;
|
||||||
|
case FileObserver.CLOSE_WRITE:
|
||||||
|
// Log.i("RecursiveFileObserver", "CLOSE_WRITE: " + path);
|
||||||
|
break;
|
||||||
|
case FileObserver.DELETE:
|
||||||
|
// Log.i("RecursiveFileObserver", "DELETE: " + path);
|
||||||
|
break;
|
||||||
|
case FileObserver.DELETE_SELF:
|
||||||
|
// Log.i("RecursiveFileObserver", "DELETE_SELF: " + path);
|
||||||
|
break;
|
||||||
|
case FileObserver.MODIFY:
|
||||||
|
// Log.i("RecursiveFileObserver", "MODIFY: " + path);
|
||||||
|
break;
|
||||||
|
case FileObserver.MOVE_SELF:
|
||||||
|
// Log.i("RecursiveFileObserver", "MOVE_SELF: " + path);
|
||||||
|
break;
|
||||||
|
case FileObserver.MOVED_FROM:
|
||||||
|
// Log.i("RecursiveFileObserver", "MOVED_FROM: " + path);
|
||||||
|
break;
|
||||||
|
case FileObserver.MOVED_TO:
|
||||||
|
// Log.i("RecursiveFileObserver", "MOVED_TO: " + path);
|
||||||
|
break;
|
||||||
|
case FileObserver.OPEN:
|
||||||
|
// Log.i("RecursiveFileObserver", "OPEN: " + path);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Log.i("RecursiveFileObserver", "DEFAULT(" + event + " : " + path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor single directory and dispatch all events to its parent, with full
|
||||||
|
* path.
|
||||||
|
*/
|
||||||
|
class SingleFileObserver extends FileObserver {
|
||||||
|
String mPath;
|
||||||
|
|
||||||
|
public SingleFileObserver(String path) {
|
||||||
|
this(path, ALL_EVENTS);
|
||||||
|
mPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleFileObserver(String path, int mask) {
|
||||||
|
super(path, mask);
|
||||||
|
mPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEvent(int event, String path) {
|
||||||
|
String newPath = mPath + "/" + path;
|
||||||
|
MultiFileObserver .this.onEvent(event, newPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -135,6 +135,7 @@ fun getRoot(ignoreCheck: Boolean): AccessibilityNodeInfo {
|
|||||||
* 后退
|
* 后退
|
||||||
*/
|
*/
|
||||||
fun backPress() {
|
fun backPress() {
|
||||||
|
val clazz = WeworkController.weworkService.currentClass
|
||||||
val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView)
|
val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView)
|
||||||
if (textView != null && textView.text.isNullOrBlank() && AccessibilityUtil.performClick(textView, retry = false)) {
|
if (textView != null && textView.text.isNullOrBlank() && AccessibilityUtil.performClick(textView, retry = false)) {
|
||||||
LogUtils.v("找到回退按钮")
|
LogUtils.v("找到回退按钮")
|
||||||
@@ -164,7 +165,8 @@ fun backPress() {
|
|||||||
} else {
|
} else {
|
||||||
LogUtils.d("未找到对话框 点击bar中心")
|
LogUtils.d("未找到对话框 点击bar中心")
|
||||||
AccessibilityUtil.performXYClick(WeworkController.weworkService, ScreenUtils.getScreenWidth() / 2F, BarUtils.getStatusBarHeight() * 2F)
|
AccessibilityUtil.performXYClick(WeworkController.weworkService, ScreenUtils.getScreenWidth() / 2F, BarUtils.getStatusBarHeight() * 2F)
|
||||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
sleep(Constant.CHANGE_PAGE_INTERVAL * 2)
|
||||||
|
if (WeworkController.weworkService.currentClass == clazz) {
|
||||||
val firstEmptyTextView = AccessibilityUtil.findAllByClazz(getRoot(), Views.TextView).firstOrNull { it.text.isNullOrEmpty() }
|
val firstEmptyTextView = AccessibilityUtil.findAllByClazz(getRoot(), Views.TextView).firstOrNull { it.text.isNullOrEmpty() }
|
||||||
if (firstEmptyTextView != null && firstEmptyTextView.isClickable) {
|
if (firstEmptyTextView != null && firstEmptyTextView.isClickable) {
|
||||||
AccessibilityUtil.performClick(firstEmptyTextView)
|
AccessibilityUtil.performClick(firstEmptyTextView)
|
||||||
@@ -174,6 +176,7 @@ fun backPress() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ object MyLooper {
|
|||||||
fun init() {
|
fun init() {
|
||||||
LogUtils.i("init myLooper...")
|
LogUtils.i("init myLooper...")
|
||||||
SPUtils.getInstance("noTipMessage").clear()
|
SPUtils.getInstance("noTipMessage").clear()
|
||||||
|
SPUtils.getInstance("lastSyncMessage").clear()
|
||||||
|
SPUtils.getInstance("noSyncMessage").clear()
|
||||||
SPUtils.getInstance("limit").clear()
|
SPUtils.getInstance("limit").clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -334,7 +334,8 @@ object WeworkController {
|
|||||||
message.fileUrl,
|
message.fileUrl,
|
||||||
message.fileBase64,
|
message.fileBase64,
|
||||||
message.fileType,
|
message.fileType,
|
||||||
message.extraText
|
message.extraText,
|
||||||
|
message.maxRetryCount
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,19 @@ package org.yameida.worktool.service
|
|||||||
|
|
||||||
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.LogUtils
|
import com.blankj.utilcode.util.*
|
||||||
import com.blankj.utilcode.util.SPUtils
|
|
||||||
import org.yameida.worktool.Constant
|
import org.yameida.worktool.Constant
|
||||||
import org.yameida.worktool.Demo
|
import org.yameida.worktool.Demo
|
||||||
import org.yameida.worktool.model.WeworkMessageBean
|
import org.yameida.worktool.model.WeworkMessageBean
|
||||||
|
import org.yameida.worktool.observer.MultiFileObserver
|
||||||
import org.yameida.worktool.service.WeworkController.mainLoopRunning
|
import org.yameida.worktool.service.WeworkController.mainLoopRunning
|
||||||
import org.yameida.worktool.utils.*
|
import org.yameida.worktool.utils.*
|
||||||
|
import java.io.File
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.lang.StringBuilder
|
import java.lang.StringBuilder
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取数据类型 201 202 主循环
|
* 获取数据类型 201 202 主循环
|
||||||
@@ -26,7 +30,7 @@ object WeworkLoopImpl {
|
|||||||
mainLoopRunning = true
|
mainLoopRunning = true
|
||||||
try {
|
try {
|
||||||
while (mainLoopRunning) {
|
while (mainLoopRunning) {
|
||||||
if (!isAtHome() && WeworkRoomUtil.getRoomType(false) != WeworkMessageBean.ROOM_TYPE_UNKNOWN) {
|
if (!isAtHome()) {
|
||||||
LogUtils.d("当前在房间: ")
|
LogUtils.d("当前在房间: ")
|
||||||
getChatMessageList()
|
getChatMessageList()
|
||||||
if (mainLoopRunning) {
|
if (mainLoopRunning) {
|
||||||
@@ -112,7 +116,7 @@ object WeworkLoopImpl {
|
|||||||
if (titleList.contains("对方正在输入…")) {
|
if (titleList.contains("对方正在输入…")) {
|
||||||
titleList = WeworkRoomUtil.getFriendName()
|
titleList = WeworkRoomUtil.getFriendName()
|
||||||
}
|
}
|
||||||
if (titleList.size > 0) {
|
if (roomType != WeworkMessageBean.ROOM_TYPE_UNKNOWN && titleList.size > 0) {
|
||||||
val title = titleList.joinToString()
|
val title = titleList.joinToString()
|
||||||
LogUtils.v("聊天: $title")
|
LogUtils.v("聊天: $title")
|
||||||
log("聊天: $title")
|
log("聊天: $title")
|
||||||
@@ -128,7 +132,7 @@ object WeworkLoopImpl {
|
|||||||
for (i in 0 until list.childCount) {
|
for (i in 0 until list.childCount) {
|
||||||
val item = list.getChild(i)
|
val item = list.getChild(i)
|
||||||
if (item != null && item.childCount > 0) {
|
if (item != null && item.childCount > 0) {
|
||||||
messageList.add(parseChatMessageItem(item, roomType))
|
messageList.add(parseChatMessageItem(item, titleList, roomType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,7 +144,7 @@ object WeworkLoopImpl {
|
|||||||
for (i in 0 until list2.childCount) {
|
for (i in 0 until list2.childCount) {
|
||||||
val item = list2.getChild(i)
|
val item = list2.getChild(i)
|
||||||
if (item != null && item.childCount > 0) {
|
if (item != null && item.childCount > 0) {
|
||||||
messageList2.add(parseChatMessageItem(item, roomType))
|
messageList2.add(parseChatMessageItem(item, titleList, roomType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,6 +163,7 @@ object WeworkLoopImpl {
|
|||||||
null
|
null
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
SPUtils.getInstance("lastSyncMessage").put(title, messageList.last().itemMessageList.lastOrNull()?.text)
|
||||||
//推测是否回复并在房间等待指令
|
//推测是否回复并在房间等待指令
|
||||||
if (needInfer) {
|
if (needInfer) {
|
||||||
val lastMessage = messageList.lastOrNull()
|
val lastMessage = messageList.lastOrNull()
|
||||||
@@ -203,6 +208,20 @@ object WeworkLoopImpl {
|
|||||||
LogUtils.e("未找到聊天消息列表")
|
LogUtils.e("未找到聊天消息列表")
|
||||||
error("未找到聊天消息列表")
|
error("未找到聊天消息列表")
|
||||||
}
|
}
|
||||||
|
} else if (Constant.autoPublishComment && WeworkController.weworkService.currentClass == "com.tencent.wework.moments.controller.MomentsIndexListActivity") {
|
||||||
|
LogUtils.d("自动发表朋友圈")
|
||||||
|
val tvGoPublish = AccessibilityUtil.findOneByText(getRoot(), "去发表", exact = true)
|
||||||
|
if (tvGoPublish != null) {
|
||||||
|
AccessibilityUtil.performClick(tvGoPublish)
|
||||||
|
AccessibilityExtraUtil.loadingPage("MomentsEnterpriseNotificationListActivity")
|
||||||
|
val tvPublishList = AccessibilityUtil.findAllByText(getRoot(), "发表", exact = true)
|
||||||
|
LogUtils.d("发现${tvPublishList.size}条待发送")
|
||||||
|
for (tvPublish in tvPublishList) {
|
||||||
|
AccessibilityUtil.performClick(tvPublish)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogUtils.v("退出非聊天房间 ${WeworkController.weworkService.currentClass}")
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -280,8 +299,9 @@ object WeworkLoopImpl {
|
|||||||
val listview = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView, Views.ListView, Views.ViewGroup)
|
val listview = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView, Views.ListView, Views.ViewGroup)
|
||||||
if (listview != null && listview.childCount >= 2) {
|
if (listview != null && listview.childCount >= 2) {
|
||||||
if (hasNewMessage != null) {
|
if (hasNewMessage != null) {
|
||||||
|
//发现新消息
|
||||||
if (checkUnreadChatRoom(listview)) {
|
if (checkUnreadChatRoom(listview)) {
|
||||||
//如果有红点 点击进入聊天页
|
//如果房间有红点 点击进入聊天页
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
AccessibilityUtil.clickByNode(WeworkController.weworkService, hasNewMessage)
|
AccessibilityUtil.clickByNode(WeworkController.weworkService, hasNewMessage)
|
||||||
@@ -290,14 +310,18 @@ object WeworkLoopImpl {
|
|||||||
sleep(Constant.POP_WINDOW_INTERVAL / 5)
|
sleep(Constant.POP_WINDOW_INTERVAL / 5)
|
||||||
//双击消息再试一次
|
//双击消息再试一次
|
||||||
if (checkUnreadChatRoom(listview)) {
|
if (checkUnreadChatRoom(listview)) {
|
||||||
//如果有红点 点击进入聊天页
|
//如果房间有红点 点击进入聊天页
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
//未发现新消息
|
||||||
if (checkNoTipMessage(listview) == 1) {
|
if (checkNoTipMessage(listview) == 1) {
|
||||||
//如果发现拉入群聊/修改群名/移出群聊 点击进入聊天页
|
//如果发现拉入群聊/修改群名/移出群聊 点击进入聊天页
|
||||||
return true
|
return true
|
||||||
|
} else if (checkNoSyncMessage(listview) == 1) {
|
||||||
|
//消息不一致
|
||||||
|
return true
|
||||||
} else {
|
} else {
|
||||||
LogUtils.v("未发现新消息或无提示消息")
|
LogUtils.v("未发现新消息或无提示消息")
|
||||||
}
|
}
|
||||||
@@ -336,6 +360,9 @@ object WeworkLoopImpl {
|
|||||||
if (checkNoTipMessage(listview) != 0) {
|
if (checkNoTipMessage(listview) != 0) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if (checkNoSyncMessage(listview) != 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -388,14 +415,14 @@ object WeworkLoopImpl {
|
|||||||
val listBriefList = arrayListOf<List<CharSequence>>()
|
val listBriefList = arrayListOf<List<CharSequence>>()
|
||||||
for (i in 0 until list.childCount) {
|
for (i in 0 until list.childCount) {
|
||||||
val item = list.getChild(i)
|
val item = list.getChild(i)
|
||||||
val tvList = AccessibilityUtil.findAllOnceByClazz(item, Views.TextView).mapNotNull { it.text }
|
val tvList = AccessibilityUtil.findAllOnceByClazz(item, Views.TextView).mapNotNull { it.text?.toString() }
|
||||||
listBriefList.add(tvList)
|
listBriefList.add(tvList)
|
||||||
//tvList title/time/content
|
//tvList title/time/content
|
||||||
if (tvList.size == 3) {
|
if (tvList.size == 3) {
|
||||||
//只查看最近一周内的消息
|
//只查看最近一周内的消息
|
||||||
if (tvList[1].isBlank() || tvList[1].contains("(刚刚)|(分钟前)|(上午)|(下午)|(昨天)|(星期)|(日程)|(会议)".toRegex())) {
|
if (tvList[1].isBlank() || tvList[1].contains("(刚刚)|(分钟前)|(上午)|(下午)|(昨天)|(星期)|(日程)|(会议)".toRegex())) {
|
||||||
if (tvList[2].contains("(移出了群聊)|(邀请你加入了)|(修改群名为)|(此群为外部群)|(加入了外部群)".toRegex())) {
|
if (tvList[2].contains("(移出了群聊)|(邀请你加入了)|(修改群名为)|(此群为外部群)|(加入了外部群)".toRegex())) {
|
||||||
val interval = System.currentTimeMillis() / 1000 - SPUtils.getInstance("noTipMessage").getLong(tvList[0].toString(), 0)
|
val interval = System.currentTimeMillis() / 1000 - SPUtils.getInstance("noTipMessage").getLong(tvList[0], 0)
|
||||||
if (interval > 3600) {
|
if (interval > 3600) {
|
||||||
LogUtils.i("发现无提示消息: $tvList")
|
LogUtils.i("发现无提示消息: $tvList")
|
||||||
log("发现无提示消息: $tvList")
|
log("发现无提示消息: $tvList")
|
||||||
@@ -404,7 +431,7 @@ object WeworkLoopImpl {
|
|||||||
} else {
|
} else {
|
||||||
AccessibilityUtil.clickByNode(WeworkController.weworkService, item)
|
AccessibilityUtil.clickByNode(WeworkController.weworkService, item)
|
||||||
}
|
}
|
||||||
SPUtils.getInstance("noTipMessage").put(tvList[0].toString(), System.currentTimeMillis() / 1000)
|
SPUtils.getInstance("noTipMessage").put(tvList[0], System.currentTimeMillis() / 1000)
|
||||||
return 1
|
return 1
|
||||||
} else {
|
} else {
|
||||||
LogUtils.v("发现无提示消息: $tvList 消息在 $interval 秒前已被查看")
|
LogUtils.v("发现无提示消息: $tvList 消息在 $interval 秒前已被查看")
|
||||||
@@ -418,11 +445,54 @@ object WeworkLoopImpl {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查首页-聊天列表是否有不一致消息
|
||||||
|
* @return -1当前列表不存在一周内消息 0未发现不一致消息 1发现不一致消息
|
||||||
|
*/
|
||||||
|
private fun checkNoSyncMessage(list: AccessibilityNodeInfo): Int {
|
||||||
|
list.refresh()
|
||||||
|
val listBriefList = arrayListOf<List<CharSequence>>()
|
||||||
|
for (i in 0 until list.childCount) {
|
||||||
|
val item = list.getChild(i)
|
||||||
|
val tvList = AccessibilityUtil.findAllOnceByClazz(item, Views.TextView).mapNotNull { it.text?.toString() }
|
||||||
|
listBriefList.add(tvList)
|
||||||
|
//tvList title/time/content
|
||||||
|
if (tvList.size == 3) {
|
||||||
|
//只查看最近一周内的消息
|
||||||
|
val title = tvList[0]
|
||||||
|
if (tvList[1].isBlank() || tvList[1].contains("(刚刚)|(分钟前)|(上午)|(下午)|(昨天)|(星期)|(日程)|(会议)".toRegex())) {
|
||||||
|
val lastSyncMessage = SPUtils.getInstance("lastSyncMessage").getString(title, null)
|
||||||
|
?: continue
|
||||||
|
if (tvList[2].contains(lastSyncMessage.replace("\n", " "))) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (SPUtils.getInstance("noSyncMessage").getString(title) != lastSyncMessage) {
|
||||||
|
LogUtils.e("发现不一致消息: $tvList")
|
||||||
|
error("发现不一致消息: $tvList $lastSyncMessage")
|
||||||
|
SPUtils.getInstance("noSyncMessage").put(title, lastSyncMessage)
|
||||||
|
if (AccessibilityUtil.performClick(item)) {
|
||||||
|
//进入聊天页 下一步 getChatMessageList
|
||||||
|
} else {
|
||||||
|
AccessibilityUtil.clickByNode(WeworkController.weworkService, item)
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
LogUtils.v("消息多次不一致: $tvList")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析消息列表里的一条消息
|
* 解析消息列表里的一条消息
|
||||||
*/
|
*/
|
||||||
private fun parseChatMessageItem(
|
private fun parseChatMessageItem(
|
||||||
node: AccessibilityNodeInfo,
|
node: AccessibilityNodeInfo,
|
||||||
|
titleList: ArrayList<String>,
|
||||||
roomType: Int
|
roomType: Int
|
||||||
): WeworkMessageBean.SubMessageBean {
|
): WeworkMessageBean.SubMessageBean {
|
||||||
val message: WeworkMessageBean.SubMessageBean
|
val message: WeworkMessageBean.SubMessageBean
|
||||||
@@ -466,6 +536,52 @@ object WeworkLoopImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
message = WeworkMessageBean.SubMessageBean(0, textType, itemMessageList, nameList)
|
message = WeworkMessageBean.SubMessageBean(0, textType, itemMessageList, nameList)
|
||||||
|
//图片类型特殊处理
|
||||||
|
if (Constant.pushImage && textType == 2) {
|
||||||
|
val lastPicCreateTime = MultiFileObserver.lastPicCreateTime
|
||||||
|
val lastPicPath = MultiFileObserver.lastPicPath
|
||||||
|
LogUtils.d("发现图片类型应该点击")
|
||||||
|
AccessibilityUtil.performClickWithSon(relativeLayoutContent)
|
||||||
|
AccessibilityExtraUtil.loadingPage("com.tencent.wework.msg.controller.ShowImageController", Constant.CHANGE_PAGE_INTERVAL)
|
||||||
|
LogUtils.d("发现图片类型 查看图片检查有无新图片产生")
|
||||||
|
if (MultiFileObserver.lastPicCreateTime > lastPicCreateTime) {
|
||||||
|
LogUtils.d("正在下载图片...")
|
||||||
|
var downloading = true
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
var currentTime = startTime
|
||||||
|
while (currentTime - startTime < Constant.LONG_INTERVAL) {
|
||||||
|
if (!lastPicPath.equals(MultiFileObserver.lastPicPath)) {
|
||||||
|
LogUtils.d("下载图片完成")
|
||||||
|
downloading = false
|
||||||
|
try {
|
||||||
|
val df = SimpleDateFormat("MMdd_HHmmss")
|
||||||
|
val targetPath = "${
|
||||||
|
Utils.getApp().getExternalFilesDir("copy")
|
||||||
|
}/${df.format(Date())}/${File(MultiFileObserver.lastPicPath).name}.png"
|
||||||
|
if (FileUtils.copy(MultiFileObserver.lastPicPath, targetPath)) {
|
||||||
|
LogUtils.d("复制图片完成: $targetPath")
|
||||||
|
} else {
|
||||||
|
LogUtils.e("复制图片失败 请检查权限: $targetPath")
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
LogUtils.e("接收图片出错", e)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sleep(Constant.POP_WINDOW_INTERVAL / 5)
|
||||||
|
currentTime = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
if (downloading) {
|
||||||
|
LogUtils.e("下载图片失败")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogUtils.d("该图片已下载 忽略")
|
||||||
|
}
|
||||||
|
while (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 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
|
||||||
|
|||||||
@@ -549,8 +549,10 @@ object WeworkOperationImpl {
|
|||||||
fileUrl: String?,
|
fileUrl: String?,
|
||||||
fileBase64: String?,
|
fileBase64: String?,
|
||||||
fileType: String,
|
fileType: String,
|
||||||
extraText: String? = null
|
extraText: String? = null,
|
||||||
|
maxRetryCount: Int? = null
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
val retryCount = maxRetryCount ?: 1
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
if (!PermissionUtils.isGrantedDrawOverlays()) {
|
if (!PermissionUtils.isGrantedDrawOverlays()) {
|
||||||
LogUtils.e("未打开悬浮窗权限")
|
LogUtils.e("未打开悬浮窗权限")
|
||||||
@@ -601,6 +603,9 @@ object WeworkOperationImpl {
|
|||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
LogUtils.e("文件转发失败: $objectName")
|
LogUtils.e("文件转发失败: $objectName")
|
||||||
|
if (retryCount > 0) {
|
||||||
|
return pushFile(message, titleList, objectName, fileUrl, fileBase64, fileType, extraText, retryCount - 1)
|
||||||
|
}
|
||||||
uploadCommandResult(
|
uploadCommandResult(
|
||||||
message,
|
message,
|
||||||
ExecCallbackBean.ERROR_RELAY,
|
ExecCallbackBean.ERROR_RELAY,
|
||||||
@@ -611,6 +616,9 @@ object WeworkOperationImpl {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogUtils.e("文件存储本地失败 $filePath")
|
LogUtils.e("文件存储本地失败 $filePath")
|
||||||
|
if (retryCount > 0) {
|
||||||
|
return pushFile(message, titleList, objectName, fileUrl, fileBase64, fileType, extraText, retryCount - 1)
|
||||||
|
}
|
||||||
uploadCommandResult(
|
uploadCommandResult(
|
||||||
message,
|
message,
|
||||||
ExecCallbackBean.ERROR_FILE_STORAGE,
|
ExecCallbackBean.ERROR_FILE_STORAGE,
|
||||||
@@ -621,6 +629,9 @@ object WeworkOperationImpl {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogUtils.e("文件下载失败")
|
LogUtils.e("文件下载失败")
|
||||||
|
if (retryCount > 0) {
|
||||||
|
return pushFile(message, titleList, objectName, fileUrl, fileBase64, fileType, extraText, retryCount - 1)
|
||||||
|
}
|
||||||
uploadCommandResult(
|
uploadCommandResult(
|
||||||
message,
|
message,
|
||||||
ExecCallbackBean.ERROR_FILE_DOWNLOAD,
|
ExecCallbackBean.ERROR_FILE_DOWNLOAD,
|
||||||
@@ -668,6 +679,9 @@ object WeworkOperationImpl {
|
|||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
LogUtils.e("文件转发失败: $objectName")
|
LogUtils.e("文件转发失败: $objectName")
|
||||||
|
if (retryCount > 0) {
|
||||||
|
return pushFile(message, titleList, objectName, fileUrl, fileBase64, fileType, extraText, retryCount - 1)
|
||||||
|
}
|
||||||
uploadCommandResult(
|
uploadCommandResult(
|
||||||
message,
|
message,
|
||||||
ExecCallbackBean.ERROR_RELAY,
|
ExecCallbackBean.ERROR_RELAY,
|
||||||
@@ -678,6 +692,9 @@ object WeworkOperationImpl {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogUtils.e("文件存储本地失败 $filePath")
|
LogUtils.e("文件存储本地失败 $filePath")
|
||||||
|
if (retryCount > 0) {
|
||||||
|
return pushFile(message, titleList, objectName, fileUrl, fileBase64, fileType, extraText, retryCount - 1)
|
||||||
|
}
|
||||||
uploadCommandResult(
|
uploadCommandResult(
|
||||||
message,
|
message,
|
||||||
ExecCallbackBean.ERROR_FILE_STORAGE,
|
ExecCallbackBean.ERROR_FILE_STORAGE,
|
||||||
@@ -687,6 +704,10 @@ object WeworkOperationImpl {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
LogUtils.e("未找到文件资源参数")
|
||||||
|
if (retryCount > 0) {
|
||||||
|
return pushFile(message, titleList, objectName, fileUrl, fileBase64, fileType, extraText, retryCount - 1)
|
||||||
|
}
|
||||||
uploadCommandResult(
|
uploadCommandResult(
|
||||||
message,
|
message,
|
||||||
ExecCallbackBean.ERROR_ILLEGAL_DATA,
|
ExecCallbackBean.ERROR_ILLEGAL_DATA,
|
||||||
@@ -1059,7 +1080,9 @@ object WeworkOperationImpl {
|
|||||||
if (tvCorp != null) {
|
if (tvCorp != null) {
|
||||||
LogUtils.d("找到目标企业: $objectName")
|
LogUtils.d("找到目标企业: $objectName")
|
||||||
AccessibilityUtil.performClick(tvCorp)
|
AccessibilityUtil.performClick(tvCorp)
|
||||||
|
uploadCommandResult(message, ExecCallbackBean.SUCCESS, "切换企业成功: $objectName", startTime)
|
||||||
goHome()
|
goHome()
|
||||||
|
WeworkGetImpl.getMyInfo(message)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
LogUtils.e("未找到目标企业: $objectName")
|
LogUtils.e("未找到目标企业: $objectName")
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.content.Context
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import org.yameida.worktool.utils.envcheck.CheckRoot
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
object FlowPermissionHelper {
|
object FlowPermissionHelper {
|
||||||
@@ -26,6 +27,10 @@ object FlowPermissionHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun canBackgroundStart(context: Context): Boolean {
|
fun canBackgroundStart(context: Context): Boolean {
|
||||||
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1 || CheckRoot.isDeviceRooted()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
if (isXiaoMi()) {
|
if (isXiaoMi()) {
|
||||||
return isXiaomiBgStartPermissionAllowed(context)
|
return isXiaomiBgStartPermissionAllowed(context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,13 @@ import org.yameida.worktool.R
|
|||||||
import org.yameida.worktool.model.network.CheckUpdateResult
|
import org.yameida.worktool.model.network.CheckUpdateResult
|
||||||
import org.yameida.worktool.model.network.GetMyConfigResult
|
import org.yameida.worktool.model.network.GetMyConfigResult
|
||||||
import update.UpdateAppUtils
|
import update.UpdateAppUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
object HttpUtil {
|
object HttpUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查更新
|
||||||
|
*/
|
||||||
fun checkUpdate() {
|
fun checkUpdate() {
|
||||||
OkGo.get<String>(Constant.getCheckUpdateUrl())
|
OkGo.get<String>(Constant.getCheckUpdateUrl())
|
||||||
.execute(object : StringCallback() {
|
.execute(object : StringCallback() {
|
||||||
@@ -63,6 +67,9 @@ object HttpUtil {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取机器人配置
|
||||||
|
*/
|
||||||
fun getMyConfig(toast: Boolean = true) {
|
fun getMyConfig(toast: Boolean = true) {
|
||||||
if (Constant.robotId.isBlank()) {
|
if (Constant.robotId.isBlank()) {
|
||||||
if (toast) {
|
if (toast) {
|
||||||
@@ -101,4 +108,24 @@ object HttpUtil {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送图片
|
||||||
|
*/
|
||||||
|
fun pushImage(url: String, groupName: String, receivedName: String?, imagePath: String) {
|
||||||
|
OkGo.post<String>(url)
|
||||||
|
.params("groupName", groupName)
|
||||||
|
.params("receivedName", receivedName ?: "")
|
||||||
|
.params("image", File(imagePath))
|
||||||
|
.execute(object : StringCallback() {
|
||||||
|
override fun onSuccess(response: Response<String>) {
|
||||||
|
LogUtils.d("推送图片成功: $groupName $receivedName $imagePath")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(response: Response<String>) {
|
||||||
|
ToastUtils.showLong("推送图片失败")
|
||||||
|
LogUtils.e("推送图片失败")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.yameida.worktool.utils;
|
||||||
|
|
||||||
|
import com.blankj.utilcode.util.LogUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ImageDepthSizeUtil {
|
||||||
|
|
||||||
|
public static boolean checkRawImage(String path) {
|
||||||
|
try {
|
||||||
|
File file = new File(path);
|
||||||
|
FileInputStream fileInputStream = new FileInputStream(file);
|
||||||
|
byte[] b = new byte[1000000];
|
||||||
|
fileInputStream.read(b);
|
||||||
|
int bitsPerPixel = (b[25] & 0xff) == 2 || (b[25] & 0xff) == 6 ? (b[24] & 0xff) * 3 : b[24] & 0xff;
|
||||||
|
LogUtils.v("path: " + path, "bitsPerPixel: " + bitsPerPixel);
|
||||||
|
return bitsPerPixel == 24;
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.e("ImageDepthSize Check Error", e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ public class PermissionPageManagement {
|
|||||||
* @param activity
|
* @param activity
|
||||||
*/
|
*/
|
||||||
public static void goToSetting(Activity activity){
|
public static void goToSetting(Activity activity){
|
||||||
|
try {
|
||||||
switch (Build.MANUFACTURER) {
|
switch (Build.MANUFACTURER) {
|
||||||
case MANUFACTURER_HUAWEI:
|
case MANUFACTURER_HUAWEI:
|
||||||
Huawei(activity);
|
Huawei(activity);
|
||||||
@@ -62,6 +63,10 @@ public class PermissionPageManagement {
|
|||||||
Log.e("goToSetting", "目前暂不支持此系统");
|
Log.e("goToSetting", "目前暂不支持此系统");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("goToSetting", "Error 目前暂不支持此系统");
|
||||||
|
ApplicationInfo(activity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Huawei(Activity activity) {
|
public static void Huawei(Activity activity) {
|
||||||
|
|||||||
26
app/src/main/java/org/yameida/worktool/utils/RuntimeUtil.kt
Normal file
26
app/src/main/java/org/yameida/worktool/utils/RuntimeUtil.kt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package org.yameida.worktool.utils
|
||||||
|
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
|
object RuntimeUtil {
|
||||||
|
|
||||||
|
@Throws(Exception::class)
|
||||||
|
fun exec(cmd: String): String? {
|
||||||
|
var ret: String? = null
|
||||||
|
val p = Runtime.getRuntime().exec(arrayOf("sh", "-c", cmd))
|
||||||
|
val inputStream: InputStream = p.inputStream
|
||||||
|
val reader = BufferedReader(InputStreamReader(inputStream))
|
||||||
|
var line: String? = reader.readLine()
|
||||||
|
while (line != null) {
|
||||||
|
ret = line
|
||||||
|
line = reader.readLine()
|
||||||
|
}
|
||||||
|
p.waitFor()
|
||||||
|
inputStream.close()
|
||||||
|
reader.close()
|
||||||
|
p.destroy()
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user