update root&xp检测提示;从外部群添加好友;修改好友信息;建群达到上限提示
This commit is contained in:
@@ -19,6 +19,7 @@ object Constant {
|
||||
val transformation = "AES/CBC/PKCS7Padding"
|
||||
var encryptType = SPUtils.getInstance().getInt("encryptType", 1)
|
||||
var autoReply = SPUtils.getInstance().getInt("autoReply", 1)
|
||||
var groupStrict = false
|
||||
var host: String
|
||||
get() = SPUtils.getInstance().getString("host", DEFAULT_HOST)
|
||||
set(value) {
|
||||
|
||||
@@ -21,6 +21,8 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.yameida.worktool.utils.HostTestHelper
|
||||
import org.yameida.worktool.utils.PermissionHelper
|
||||
import org.yameida.worktool.utils.PermissionPageManagement
|
||||
import org.yameida.worktool.utils.envcheck.CheckHook
|
||||
import org.yameida.worktool.utils.envcheck.CheckRoot
|
||||
|
||||
|
||||
class ListenActivity : AppCompatActivity() {
|
||||
@@ -87,7 +89,15 @@ class ListenActivity : AppCompatActivity() {
|
||||
true
|
||||
}
|
||||
val version = "${AppUtils.getAppVersionName()} Android ${DeviceUtils.getSDKVersionName()} ${DeviceUtils.getManufacturer()} ${DeviceUtils.getModel()}"
|
||||
val deviceRooted = CheckRoot.isDeviceRooted()
|
||||
val hook = CheckHook.isHook(applicationContext)
|
||||
if (hook) {
|
||||
tv_version.text = "当前设备存在侵入代码,请勿在本设备使用本程序!!!"
|
||||
} else if (deviceRooted) {
|
||||
tv_version.text = "$version\n本设备已Root,存在一定风险!"
|
||||
} else {
|
||||
tv_version.text = version
|
||||
}
|
||||
val workVersionName = AppUtils.getAppInfo(Constant.PACKAGE_NAMES)?.versionName
|
||||
when (workVersionName) {
|
||||
null -> {
|
||||
@@ -107,6 +117,8 @@ class ListenActivity : AppCompatActivity() {
|
||||
}
|
||||
SPUtils.getInstance().put("appVersion", version)
|
||||
SPUtils.getInstance().put("workVersion", workVersionName)
|
||||
SPUtils.getInstance().put("deviceRooted", deviceRooted)
|
||||
SPUtils.getInstance().put("hook", hook)
|
||||
}
|
||||
|
||||
private fun initAccessibility() {
|
||||
@@ -215,7 +227,7 @@ class ListenActivity : AppCompatActivity() {
|
||||
if (text.matches("ws{1,2}://[^/]+.*".toRegex())) {
|
||||
Constant.host = text
|
||||
tv_host.text = text
|
||||
HostTestHelper.test()
|
||||
HostTestHelper.testWs()
|
||||
commentDialog.dismiss()
|
||||
} else {
|
||||
ToastUtils.showLong("格式异常!")
|
||||
|
||||
@@ -32,6 +32,8 @@ public class WeworkMessageBean {
|
||||
* 按手机号添加好友 ADD_FRIEND_BY_PHONE
|
||||
* 展示群信息 SHOW_GROUP_INFO
|
||||
* 推送文件(网络图片视频和文件等) PUSH_FILE
|
||||
* 解散群聊 DISMISS_GROUP
|
||||
* 从外部群添加好友 ADD_FRIEND_BY_GROUP
|
||||
* <p>
|
||||
* 非操作类型 300
|
||||
* 机器人普通日志记录 ROBOT_LOG
|
||||
@@ -66,6 +68,7 @@ public class WeworkMessageBean {
|
||||
public static final int DELETED_ANTI_HARASSMENT_RULE = 217;
|
||||
public static final int PUSH_FILE = 218;
|
||||
public static final int DISMISS_GROUP = 219;
|
||||
public static final int ADD_FRIEND_BY_GROUP = 220;
|
||||
|
||||
public static final int ROBOT_LOG = 301;
|
||||
public static final int ROBOT_ERROR_LOG = 302;
|
||||
@@ -287,6 +290,20 @@ public class WeworkMessageBean {
|
||||
public int hashCode() {
|
||||
return Objects.hash(phone, name, markName, markCorp, markExtra, tagList, newFriend, leavingMsg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Friend{" +
|
||||
"phone='" + phone + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", markName='" + markName + '\'' +
|
||||
", markCorp='" + markCorp + '\'' +
|
||||
", markExtra='" + markExtra + '\'' +
|
||||
", tagList=" + tagList +
|
||||
", newFriend=" + newFriend +
|
||||
", leavingMsg='" + leavingMsg + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -117,7 +117,7 @@ fun getRoot(ignoreCheck: Boolean): AccessibilityNodeInfo {
|
||||
}
|
||||
}
|
||||
}
|
||||
sleep(1000)
|
||||
sleep(Constant.CHANGE_PAGE_INTERVAL)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -136,16 +136,19 @@ object MyLooper {
|
||||
WeworkMessageBean.PUSH_OFFICE -> {
|
||||
WeworkController.pushOffice(message)
|
||||
}
|
||||
WeworkMessageBean.PASS_ALL_FRIEND_REQUEST -> {
|
||||
}
|
||||
WeworkMessageBean.ADD_FRIEND_BY_PHONE -> {
|
||||
WeworkController.addFriendByPhone(message)
|
||||
}
|
||||
WeworkMessageBean.PUSH_FILE -> {
|
||||
WeworkController.pushFile(message)
|
||||
}
|
||||
WeworkMessageBean.DISMISS_GROUP -> {
|
||||
WeworkController.dismissGroup(message)
|
||||
}
|
||||
WeworkMessageBean.PASS_ALL_FRIEND_REQUEST -> {
|
||||
}
|
||||
WeworkMessageBean.ADD_FRIEND_BY_PHONE -> {
|
||||
WeworkController.addFriendByPhone(message)
|
||||
WeworkMessageBean.ADD_FRIEND_BY_GROUP -> {
|
||||
WeworkController.addFriendByGroup(message)
|
||||
}
|
||||
WeworkMessageBean.SHOW_GROUP_INFO -> {
|
||||
WeworkController.showGroupInfo(message)
|
||||
|
||||
@@ -187,6 +187,22 @@ object WeworkController {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 从外部群添加好友
|
||||
* @see WeworkMessageBean.ADD_FRIEND_BY_GROUP
|
||||
* @param message#groupName 外部群
|
||||
* @param message#friend 待添加用户
|
||||
*/
|
||||
@RequestMapping
|
||||
fun addFriendByGroup(message: WeworkMessageBean): Boolean {
|
||||
LogUtils.d("addFriendByGroup(): ${message.groupName} ${message.friend}")
|
||||
return WeworkOperationImpl.addFriendByGroup(
|
||||
message,
|
||||
message.groupName,
|
||||
message.friend
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送微盘图片
|
||||
* @see WeworkMessageBean.PUSH_MICRO_DISK_IMAGE
|
||||
@@ -287,7 +303,7 @@ object WeworkController {
|
||||
/**
|
||||
* 按手机号添加好友
|
||||
* @see WeworkMessageBean.ADD_FRIEND_BY_PHONE
|
||||
* @param message#friend 待添加用户列表
|
||||
* @param message#friend 待添加用户
|
||||
*/
|
||||
@RequestMapping
|
||||
fun addFriendByPhone(message: WeworkMessageBean): Boolean {
|
||||
|
||||
@@ -219,13 +219,19 @@ object WeworkOperationImpl {
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_CREATE_GROUP, "创建群失败", startTime)
|
||||
return false
|
||||
}
|
||||
if (createGroupLimit()) {
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_CREATE_GROUP_LIMIT, "建群达到上限", startTime)
|
||||
return false
|
||||
} else {
|
||||
LogUtils.v("未发现建群达到上限")
|
||||
}
|
||||
}
|
||||
if (!groupRename(groupName)) {
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_GROUP_RENAME, "创建群成功 群改名失败", startTime)
|
||||
return false
|
||||
}
|
||||
if (!groupAddMember(selectList)) {
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_GROUP_ADD_MEMBER, "创建群成功 群改名成功 群拉人失败 ${selectList?.joinToString()}", startTime)
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_GROUP_ADD_MEMBER, "创建群成功 群改名成功 群拉人失败: ${selectList?.joinToString()}", startTime)
|
||||
return false
|
||||
}
|
||||
if (!groupChangeAnnouncement(groupAnnouncement)) {
|
||||
@@ -278,11 +284,11 @@ object WeworkOperationImpl {
|
||||
return false
|
||||
}
|
||||
if (!groupAddMember(selectList, showMessageHistory == true)) {
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_GROUP_ADD_MEMBER, "进入房间成功 群改名成功 群拉人失败 ${selectList?.joinToString()}", startTime)
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_GROUP_ADD_MEMBER, "进入房间成功 群改名成功 群拉人失败: ${selectList?.joinToString()}", startTime)
|
||||
return false
|
||||
}
|
||||
if (!groupRemoveMember(removeList)) {
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_GROUP_REMOVE_MEMBER, "进入房间成功 群改名成功 群拉人成功 群踢人失败 ${removeList?.joinToString()}", startTime)
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_GROUP_REMOVE_MEMBER, "进入房间成功 群改名成功 群拉人成功 群踢人失败: ${removeList?.joinToString()}", startTime)
|
||||
return false
|
||||
}
|
||||
if (!groupChangeAnnouncement(newGroupAnnouncement)) {
|
||||
@@ -657,46 +663,21 @@ object WeworkOperationImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号添加好友
|
||||
* 手机号添加好友或修改好友信息
|
||||
* @see WeworkMessageBean.ADD_FRIEND_BY_PHONE
|
||||
* @param friend 待添加用户列表
|
||||
* @param friend 待添加用户
|
||||
*/
|
||||
fun addFriendByPhone(
|
||||
message: WeworkMessageBean,
|
||||
friend: WeworkMessageBean.Friend
|
||||
): Boolean {
|
||||
val startTime = System.currentTimeMillis()
|
||||
goHome()
|
||||
val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView, Views.ListView, Views.ViewGroup)
|
||||
if (list != null) {
|
||||
val frontNode = AccessibilityUtil.findFrontNode(list)
|
||||
val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
|
||||
if (textViewList.size >= 2) {
|
||||
val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 2]
|
||||
val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
|
||||
AccessibilityUtil.performClick(multiButton)
|
||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||
val list = AccessibilityUtil.findAllByClazz(getRoot(), Views.ListView).lastOrNull()
|
||||
if (list != null) {
|
||||
val button = AccessibilityUtil.findOneByText(list, "添加客户", "添加居民", "加微信", "加学员", exact = true)
|
||||
if (button != null) {
|
||||
AccessibilityUtil.performClick(button)
|
||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||
AccessibilityUtil.findTextAndClick(getRoot(), "搜索手机号添加")
|
||||
AccessibilityUtil.findTextInput(getRoot(), friend.phone.trim())
|
||||
if (AccessibilityUtil.findTextAndClick(getRoot(), "网络查找手机")) {
|
||||
val bothUsedTv = AccessibilityUtil.findOneByText(getRoot(), "对方同时使用", "标签", "电话")
|
||||
val bothUsedText = bothUsedTv?.text
|
||||
if (bothUsedText != null && bothUsedText.contains("对方同时使用")) {
|
||||
AccessibilityUtil.performClick(
|
||||
AccessibilityUtil.findOnceByClazz(
|
||||
AccessibilityUtil.findBackNode(bothUsedTv),
|
||||
Views.ImageView
|
||||
)
|
||||
)
|
||||
}
|
||||
if (AccessibilityUtil.findOneByText(getRoot(), "标签", "电话") != null) {
|
||||
var markTv = AccessibilityUtil.findOnceByText(getRoot(), "设置备注和描述", exact = true)
|
||||
//如果已经是好友的可以传name修改好友信息
|
||||
if (friend.phone == null && friend.name != null) {
|
||||
if (getFriendInfo(friend.name)) {
|
||||
if (AccessibilityUtil.findOneByText(getRoot(), "标签", "电话", "描述", "设置备注和描述", exact = true) != null) {
|
||||
var markTv =
|
||||
AccessibilityUtil.findOnceByText(getRoot(), "设置备注和描述", exact = true)
|
||||
if (markTv == null) {
|
||||
markTv = AccessibilityUtil.findOnceByText(getRoot(), "企业", exact = true)
|
||||
}
|
||||
@@ -729,28 +710,60 @@ object WeworkOperationImpl {
|
||||
setFriendTags(friend.tagList)
|
||||
}
|
||||
}
|
||||
//添加联系人
|
||||
val imageView =
|
||||
AccessibilityUtil.findOneByClazz(getRoot(), Views.ImageView)
|
||||
if (imageView != null) {
|
||||
val textViewList = AccessibilityUtil.findAllOnceByClazz(
|
||||
imageView.parent,
|
||||
Views.TextView
|
||||
} else {
|
||||
LogUtils.e("未找到标签")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到标签", startTime)
|
||||
return false
|
||||
}
|
||||
LogUtils.d("修改好友信息成功: ${friend.name}")
|
||||
uploadCommandResult(message, ExecCallbackBean.SUCCESS, "", startTime)
|
||||
sleep(3000)
|
||||
return true
|
||||
} else {
|
||||
LogUtils.e("未找到用户: ${friend.name}")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_TARGET, "未找到用户: ${friend.name}", startTime)
|
||||
return false
|
||||
}
|
||||
}
|
||||
//手机号添加好友
|
||||
goHome()
|
||||
val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView, Views.ListView, Views.ViewGroup)
|
||||
if (list != null) {
|
||||
val frontNode = AccessibilityUtil.findFrontNode(list)
|
||||
val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
|
||||
if (textViewList.size >= 2) {
|
||||
val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 2]
|
||||
val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
|
||||
AccessibilityUtil.performClick(multiButton)
|
||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||
val list = AccessibilityUtil.findAllByClazz(getRoot(), Views.ListView).lastOrNull()
|
||||
if (list != null) {
|
||||
val button = AccessibilityUtil.findOneByText(list, "添加客户", "添加居民", "加微信", "加学员", exact = true)
|
||||
if (button != null) {
|
||||
AccessibilityUtil.performClick(button)
|
||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||
AccessibilityUtil.findTextAndClick(getRoot(), "搜索手机号添加")
|
||||
AccessibilityUtil.findTextInput(getRoot(), friend.phone.trim())
|
||||
if (AccessibilityUtil.findTextAndClick(getRoot(), "网络查找手机")) {
|
||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||
val bothUsedTv = AccessibilityUtil.findOneByTextRegex(getRoot(), "(对方同时使用.*?)|(标签)|(电话)|(描述)|(设置备注和描述)", timeout = 2000)
|
||||
val bothUsedText = bothUsedTv?.text
|
||||
if (bothUsedText != null && bothUsedText.contains("对方同时使用")) {
|
||||
AccessibilityUtil.performClick(
|
||||
AccessibilityUtil.findOnceByClazz(
|
||||
AccessibilityUtil.findBackNode(bothUsedTv),
|
||||
Views.ImageView
|
||||
)
|
||||
)
|
||||
val filter =
|
||||
textViewList.filter { it.text != null && it.text.toString() != "微信" }
|
||||
if (filter.isNotEmpty()) {
|
||||
val tvNick = filter[0]
|
||||
LogUtils.d("好友昵称或备注名: " + tvNick.text)
|
||||
}
|
||||
}
|
||||
if (modifyFriendInfo(friend)) {
|
||||
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)
|
||||
LogUtils.d("发送添加邀请成功: ${friend.phone}")
|
||||
uploadCommandResult(message, ExecCallbackBean.SUCCESS, "", startTime)
|
||||
return true
|
||||
} else {
|
||||
@@ -770,8 +783,8 @@ object WeworkOperationImpl {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("未找到标签")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到标签", startTime)
|
||||
LogUtils.e("修改用户信息失败: ${friend.phone}")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "修改用户信息失败: ${friend.phone}", startTime)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
@@ -801,6 +814,119 @@ object WeworkOperationImpl {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从外部群添加好友
|
||||
* @see WeworkMessageBean.ADD_FRIEND_BY_PHONE
|
||||
* @param groupName 外部群
|
||||
* @param friend 待添加用户
|
||||
*/
|
||||
fun addFriendByGroup(
|
||||
message: WeworkMessageBean,
|
||||
groupName: String,
|
||||
friend: WeworkMessageBean.Friend
|
||||
): Boolean {
|
||||
val startTime = System.currentTimeMillis()
|
||||
if (WeworkRoomUtil.intoRoom(groupName) && WeworkRoomUtil.intoGroupManager()) {
|
||||
if (AccessibilityUtil.findTextAndClick(getRoot(), "查看全部群成员")) {
|
||||
val title = friend.name
|
||||
val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
|
||||
if (list != null) {
|
||||
val frontNode = AccessibilityUtil.findFrontNode(list)
|
||||
val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
|
||||
.filter { it.text == null }
|
||||
if (textViewList.size >= 2) {
|
||||
val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
|
||||
AccessibilityUtil.performClick(searchButton)
|
||||
val needTrim = title.contains(Constant.regTrimTitle)
|
||||
val trimTitle = title.replace(Constant.regTrimTitle, "")
|
||||
AccessibilityUtil.findTextInput(getRoot(), trimTitle)
|
||||
sleep(Constant.CHANGE_PAGE_INTERVAL)
|
||||
//消息页搜索结果列表
|
||||
val selectListView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
|
||||
val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
|
||||
val regex1 = "^$reverseRegexTitle" + if (needTrim) ".*?" else "(-.*)?(…)?(\\(.*?\\))?$"
|
||||
val regex2 = ".*?\\($reverseRegexTitle\\)$"
|
||||
val regex = "($regex1)|($regex2)"
|
||||
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 && searchResult.parent.childCount < 3) {
|
||||
item.refresh()
|
||||
val imageView =
|
||||
AccessibilityUtil.findOneByClazz(item, Views.ImageView, root = false)
|
||||
AccessibilityUtil.performClick(imageView)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (modifyFriendInfo(friend)) {
|
||||
if (AccessibilityUtil.findTextAndClick(getRoot(), "添加为联系人")) {
|
||||
LogUtils.d("准备发送好友邀请: ${friend.name}")
|
||||
if (!friend.leavingMsg.isNullOrEmpty()) {
|
||||
AccessibilityUtil.findTextInput(getRoot(), friend.leavingMsg)
|
||||
}
|
||||
if (AccessibilityUtil.findTextAndClick(getRoot(), "发送添加邀请", "发送申请")) {
|
||||
LogUtils.d("发送添加邀请成功: ${friend.name}")
|
||||
uploadCommandResult(message, ExecCallbackBean.SUCCESS, "", startTime)
|
||||
return true
|
||||
} else {
|
||||
if (AccessibilityUtil.findOnceByText(getRoot(), "发消息", exact = true) != null) {
|
||||
LogUtils.d("已经添加成功: ${friend.name}")
|
||||
uploadCommandResult(message, ExecCallbackBean.SUCCESS, "", startTime)
|
||||
return true
|
||||
}
|
||||
LogUtils.e("未找到发送邀请按钮")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到发送邀请按钮", startTime)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if (AccessibilityUtil.findOnceByText(getRoot(), "发消息", exact = true) != null) {
|
||||
LogUtils.e("已经添加联系人,请勿重复添加: ${friend.name}")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_REPEAT, "已经添加联系人,请勿重复添加 ${friend.name}", startTime)
|
||||
return false
|
||||
} else {
|
||||
LogUtils.e("未找到添加为联系人")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到添加为联系人", startTime)
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("修改用户信息失败: ${friend.name}")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "修改用户信息失败: ${friend.name}", startTime)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("未搜索到结果: ${friend.name}")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未搜索到结果: ${friend.name}", startTime)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("未发现搜索按钮")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未发现搜索按钮", startTime)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("未发现通讯录列表")
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未发现通讯录列表", startTime)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到查看全部群成员按钮 $groupName", startTime)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
uploadCommandResult(message, ExecCallbackBean.ERROR_INTO_ROOM, "进入房间失败 $groupName", startTime)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示群信息
|
||||
* @see WeworkMessageBean.SHOW_GROUP_INFO
|
||||
@@ -884,7 +1010,7 @@ object WeworkOperationImpl {
|
||||
if (matchSelect != null) {
|
||||
LogUtils.d("找到搜索结果: $select")
|
||||
} else {
|
||||
LogUtils.e("未搜索到结果")
|
||||
LogUtils.e("未搜索到结果: $select")
|
||||
}
|
||||
sleep(Constant.POP_WINDOW_INTERVAL)
|
||||
}
|
||||
@@ -902,18 +1028,18 @@ object WeworkOperationImpl {
|
||||
AccessibilityUtil.performClick(sendButton)
|
||||
return true
|
||||
}
|
||||
LogUtils.e("未发现发送按钮: ")
|
||||
LogUtils.e("未发现发送按钮")
|
||||
return false
|
||||
} else {
|
||||
LogUtils.e("未发现确认按钮: ")
|
||||
LogUtils.e("未发现确认按钮")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("未发现搜索和多选按钮: ")
|
||||
LogUtils.e("未发现搜索和多选按钮")
|
||||
return false
|
||||
}
|
||||
}
|
||||
LogUtils.e("未知错误: ")
|
||||
LogUtils.e("未知错误")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -936,6 +1062,15 @@ object WeworkOperationImpl {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否达到当日建群上限
|
||||
*/
|
||||
private fun createGroupLimit(): Boolean {
|
||||
val hasLimit =
|
||||
AccessibilityUtil.findOneByText(getRoot(), "新建群聊功能暂时被限制", "未验证企业", timeout = 2000)
|
||||
return hasLimit != null
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改群名称
|
||||
*/
|
||||
@@ -1047,8 +1182,8 @@ object WeworkOperationImpl {
|
||||
if (matchSelect != null) {
|
||||
LogUtils.d("找到搜索结果: $select")
|
||||
} else {
|
||||
LogUtils.e("未搜索到结果")
|
||||
return false
|
||||
LogUtils.e("未搜索到结果: $select")
|
||||
if (Constant.groupStrict) return false
|
||||
}
|
||||
}
|
||||
if (showMessageHistory) {
|
||||
@@ -1059,7 +1194,7 @@ object WeworkOperationImpl {
|
||||
if (confirmButton != null) {
|
||||
AccessibilityUtil.performClick(confirmButton)
|
||||
} else {
|
||||
LogUtils.e("未发现确认按钮: ")
|
||||
LogUtils.e("未发现确认按钮")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
@@ -1138,8 +1273,8 @@ object WeworkOperationImpl {
|
||||
if (matchSelect != null) {
|
||||
LogUtils.d("找到搜索结果: $select")
|
||||
} else {
|
||||
LogUtils.e("未搜索到结果")
|
||||
return false
|
||||
LogUtils.e("未搜索到结果: $select")
|
||||
if (Constant.groupStrict) return false
|
||||
}
|
||||
}
|
||||
val confirmButton =
|
||||
@@ -1147,7 +1282,7 @@ object WeworkOperationImpl {
|
||||
if (confirmButton != null) {
|
||||
AccessibilityUtil.performClick(confirmButton)
|
||||
} else {
|
||||
LogUtils.e("未发现移出按钮: ")
|
||||
LogUtils.e("未发现移出按钮")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
@@ -1193,10 +1328,10 @@ object WeworkOperationImpl {
|
||||
}
|
||||
sleep(3000)
|
||||
} else {
|
||||
LogUtils.e("无法进行群公告发布: ")
|
||||
LogUtils.e("无法进行群公告发布")
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("无法进行群公告发布和编辑: ")
|
||||
LogUtils.e("无法进行群公告发布和编辑")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
@@ -1225,10 +1360,10 @@ object WeworkOperationImpl {
|
||||
if (AccessibilityUtil.findTextAndClick(getRoot(), "确定")) {
|
||||
return true
|
||||
} else {
|
||||
LogUtils.e("无法进行群备注发布: ")
|
||||
LogUtils.e("无法进行群备注发布")
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("无法进行群备注修改: ")
|
||||
LogUtils.e("无法进行群备注修改")
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("未找到群公告按钮")
|
||||
@@ -1352,6 +1487,141 @@ object WeworkOperationImpl {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 从通讯录查询好友信息
|
||||
*/
|
||||
private fun getFriendInfo(title: String): Boolean {
|
||||
goHomeTab("通讯录")
|
||||
val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
|
||||
if (list != null) {
|
||||
val frontNode = AccessibilityUtil.findFrontNode(list)
|
||||
val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
|
||||
if (textViewList.size >= 2) {
|
||||
val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 2]
|
||||
val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
|
||||
AccessibilityUtil.performClick(searchButton)
|
||||
val needTrim = title.contains(Constant.regTrimTitle)
|
||||
val trimTitle = title.replace(Constant.regTrimTitle, "")
|
||||
AccessibilityUtil.findTextInput(getRoot(), trimTitle)
|
||||
sleep(Constant.CHANGE_PAGE_INTERVAL)
|
||||
//消息页搜索结果列表
|
||||
val selectListView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
|
||||
val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
|
||||
val regex1 = "^$reverseRegexTitle" + if (needTrim) ".*?" else "(-.*)?(…)?(\\(.*?\\))?$"
|
||||
val regex2 = ".*?\\($reverseRegexTitle\\)$"
|
||||
val regex = "($regex1)|($regex2)"
|
||||
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 && searchResult.parent.childCount < 3) {
|
||||
item.refresh()
|
||||
val imageView =
|
||||
AccessibilityUtil.findOneByClazz(item, Views.ImageView, root = false)
|
||||
AccessibilityUtil.performClick(imageView)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matchSelect != null) {
|
||||
LogUtils.d("找到搜索结果: $title")
|
||||
return true
|
||||
} else {
|
||||
LogUtils.e("未搜索到结果: $title")
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改好友信息
|
||||
*/
|
||||
private fun modifyFriendInfo(friend: WeworkMessageBean.Friend): Boolean {
|
||||
if (AccessibilityUtil.findOneByText(getRoot(), "标签", "电话", "描述", "设置备注和描述", exact = true) != null) {
|
||||
var markTv = AccessibilityUtil.findOnceByText(getRoot(), "设置备注和描述", exact = true)
|
||||
if (markTv == null) {
|
||||
markTv = AccessibilityUtil.findOnceByText(getRoot(), "企业", exact = true)
|
||||
}
|
||||
if (markTv == null) {
|
||||
markTv = AccessibilityUtil.findOnceByText(getRoot(), "描述", exact = true)
|
||||
}
|
||||
//设置备注
|
||||
if (markTv != null && (friend.markName != null
|
||||
|| friend.markCorp != null || friend.markExtra != null)
|
||||
) {
|
||||
AccessibilityUtil.performClick(markTv)
|
||||
val etList =
|
||||
AccessibilityUtil.findAllByClazz(getRoot(), Views.EditText, minSize = 2)
|
||||
if (etList.size >= 5) {
|
||||
//微信用户 备注/企业/电话/电话/描述
|
||||
if (friend.markName != null) {
|
||||
AccessibilityUtil.editTextInput(etList[0], friend.markName)
|
||||
}
|
||||
if (friend.markCorp != null) {
|
||||
AccessibilityUtil.editTextInput(etList[1], friend.markCorp)
|
||||
}
|
||||
if (friend.markExtra != null) {
|
||||
AccessibilityUtil.editTextInput(etList[4], friend.markExtra)
|
||||
}
|
||||
} else if (etList.size == 2) {
|
||||
//同企业内部用户 备注/描述
|
||||
if (friend.markName != null) {
|
||||
AccessibilityUtil.editTextInput(etList[0], friend.markName)
|
||||
}
|
||||
if (friend.markExtra != null) {
|
||||
AccessibilityUtil.editTextInput(etList[1], friend.markExtra)
|
||||
}
|
||||
} else if (etList.size == 3) {
|
||||
//外部企业用户 备注/电话/描述
|
||||
if (friend.markName != null) {
|
||||
AccessibilityUtil.editTextInput(etList[0], friend.markName)
|
||||
}
|
||||
if (friend.markExtra != null) {
|
||||
AccessibilityUtil.editTextInput(etList[2], friend.markExtra)
|
||||
}
|
||||
}
|
||||
AccessibilityUtil.findTextAndClick(getRoot(), "保存")
|
||||
}
|
||||
//设置标签
|
||||
if (!friend.tagList.isNullOrEmpty()) {
|
||||
if (AccessibilityUtil.findTextAndClick(getRoot(), "标签")) {
|
||||
setFriendTags(friend.tagList)
|
||||
}
|
||||
}
|
||||
//添加联系人
|
||||
val imageView =
|
||||
AccessibilityUtil.findOneByClazz(getRoot(), Views.ImageView)
|
||||
if (imageView != null) {
|
||||
val textViewList = AccessibilityUtil.findAllOnceByClazz(
|
||||
imageView.parent,
|
||||
Views.TextView
|
||||
)
|
||||
val filter =
|
||||
textViewList.filter { it.text != null && it.text.toString() != "微信" }
|
||||
if (filter.isNotEmpty()) {
|
||||
val tvNick = filter[0]
|
||||
LogUtils.d("好友昵称或备注名: ${tvNick.text}")
|
||||
}
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
if (AccessibilityUtil.findOnceByText(getRoot(), "无权查看") != null) {
|
||||
LogUtils.e("无权查看该用户")
|
||||
return false
|
||||
}
|
||||
LogUtils.e("未找到标签")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置好友标签
|
||||
*/
|
||||
@@ -1462,7 +1732,6 @@ object WeworkOperationImpl {
|
||||
)
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
LogUtils.e(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,9 @@ class WeworkService : AccessibilityService() {
|
||||
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")
|
||||
val deviceRooted = SPUtils.getInstance().getBoolean("deviceRooted", false)
|
||||
val hook = SPUtils.getInstance().getBoolean("hook", false)
|
||||
log("链接建立: $robotId appVersion: $appVersion workVersion: $workVersion deviceRooted: $deviceRooted hook: $hook")
|
||||
LogUtils.i("设置自动跳转企业微信")
|
||||
sendBroadcast(true)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
package org.yameida.worktool.utils.envcheck;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class CheckHook {
|
||||
|
||||
public static boolean isHook(Context context) {
|
||||
return isHookByPackageName(context) || isHookByStack(context) || isHookByJar();
|
||||
}
|
||||
|
||||
/**
|
||||
* 包名检测
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static boolean isHookByPackageName(Context context) {
|
||||
boolean isHook = false;
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
List<ApplicationInfo> applicationInfoList = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
|
||||
if (null == applicationInfoList) {
|
||||
return isHook;
|
||||
}
|
||||
for (ApplicationInfo applicationInfo : applicationInfoList) {
|
||||
if (applicationInfo.packageName.equals("de.robv.android.xposed.installer")) {
|
||||
Log.wtf("HookDetection", "Xposed found on the system.");
|
||||
isHook = true;
|
||||
}
|
||||
if (applicationInfo.packageName.equals("com.saurik.substrate")) {
|
||||
isHook = true;
|
||||
Log.wtf("HookDetection", "Substrate found on the system.");
|
||||
}
|
||||
}
|
||||
return isHook;
|
||||
}
|
||||
|
||||
public static boolean isHookByStack(Context context) {
|
||||
boolean isHook = false;
|
||||
try {
|
||||
throw new Exception("blah");
|
||||
} catch (Exception e) {
|
||||
int zygoteInitCallCount = 0;
|
||||
for (StackTraceElement stackTraceElement : e.getStackTrace()) {
|
||||
if (stackTraceElement.getClassName().equals("com.android.internal.os.ZygoteInit")) {
|
||||
zygoteInitCallCount++;
|
||||
if (zygoteInitCallCount == 2) {
|
||||
Log.wtf("HookDetection", "Substrate is active on the device.");
|
||||
isHook = true;
|
||||
}
|
||||
}
|
||||
if (stackTraceElement.getClassName().equals("com.saurik.substrate.MS$2") &&
|
||||
stackTraceElement.getMethodName().equals("invoked")) {
|
||||
Log.wtf("HookDetection", "A method on the stack trace has been hooked using Substrate.");
|
||||
isHook = true;
|
||||
}
|
||||
if (stackTraceElement.getClassName().equals("de.robv.android.xposed.XposedBridge") &&
|
||||
stackTraceElement.getMethodName().equals("main")) {
|
||||
Log.wtf("HookDetection", "Xposed is active on the device.");
|
||||
isHook = true;
|
||||
}
|
||||
if (stackTraceElement.getClassName().equals("de.robv.android.xposed.XposedBridge") &&
|
||||
stackTraceElement.getMethodName().equals("handleHookedMethod")) {
|
||||
Log.wtf("HookDetection", "A method on the stack trace has been hooked using Xposed.");
|
||||
isHook = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return isHook;
|
||||
}
|
||||
|
||||
public static boolean isHookByJar() {
|
||||
boolean isHook = false;
|
||||
try {
|
||||
Set<String> libraries = new HashSet();
|
||||
String mapsFilename = "/proc/" + android.os.Process.myPid() + "/maps";
|
||||
BufferedReader reader = new BufferedReader(new FileReader(mapsFilename));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.endsWith(".so") || line.endsWith(".jar")) {
|
||||
int n = line.lastIndexOf(" ");
|
||||
libraries.add(line.substring(n + 1));
|
||||
}
|
||||
}
|
||||
for (String library : libraries) {
|
||||
if (library.contains("com.saurik.substrate")) {
|
||||
Log.wtf("HookDetection", "Substrate shared object found: " + library);
|
||||
isHook = true;
|
||||
}
|
||||
if (library.contains("XposedBridge.jar")) {
|
||||
Log.wtf("HookDetection", "Xposed JAR found: " + library);
|
||||
isHook = true;
|
||||
}
|
||||
}
|
||||
reader.close();
|
||||
} catch (Exception e) {
|
||||
Log.wtf("HookDetection", e.toString());
|
||||
}
|
||||
return isHook;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
package org.yameida.worktool.utils.envcheck;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CheckRoot {
|
||||
private static String LOG_TAG = CheckRoot.class.getName();
|
||||
|
||||
public static boolean isDeviceRooted() {
|
||||
if (checkDeviceDebuggable()) {
|
||||
return true;
|
||||
}
|
||||
if (checkSuperuserApk()) {
|
||||
return true;
|
||||
}
|
||||
if (checkRootPathSU()) {
|
||||
return true;
|
||||
}
|
||||
if (checkRootWhichSU()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (checkAccessRootData()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean checkDeviceDebuggable() {
|
||||
String buildTags = android.os.Build.TAGS;
|
||||
if (buildTags != null && buildTags.contains("test-keys")) {
|
||||
Log.i(LOG_TAG, "buildTags=" + buildTags);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean checkSuperuserApk() {
|
||||
try {
|
||||
File file = new File("/system/app/Superuser.apk");
|
||||
if (file.exists()) {
|
||||
Log.i(LOG_TAG, "/system/app/Superuser.apk exist");
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean checkRootPathSU() {
|
||||
File f = null;
|
||||
final String kSuSearchPaths[] = {"/system/bin/", "/system/xbin/", "/system/sbin/", "/sbin/", "/vendor/bin/"};
|
||||
try {
|
||||
for (int i = 0; i < kSuSearchPaths.length; i++) {
|
||||
f = new File(kSuSearchPaths[i] + "su");
|
||||
if (f != null && f.exists()) {
|
||||
Log.i(LOG_TAG, "find su in : " + kSuSearchPaths[i]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean checkRootWhichSU() {
|
||||
String[] strCmd = new String[]{"/system/xbin/which", "su"};
|
||||
ArrayList<String> execResult = executeCommand(strCmd);
|
||||
if (execResult != null) {
|
||||
Log.i(LOG_TAG, "execResult=" + execResult.toString());
|
||||
return true;
|
||||
} else {
|
||||
Log.i(LOG_TAG, "execResult=null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<String> executeCommand(String[] shellCmd) {
|
||||
String line = null;
|
||||
ArrayList<String> fullResponse = new ArrayList<String>();
|
||||
Process localProcess = null;
|
||||
try {
|
||||
Log.i(LOG_TAG, "to shell exec which for find su :");
|
||||
localProcess = Runtime.getRuntime().exec(shellCmd);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(localProcess.getOutputStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(localProcess.getInputStream()));
|
||||
try {
|
||||
while ((line = in.readLine()) != null) {
|
||||
Log.i(LOG_TAG, "–> Line received: " + line);
|
||||
fullResponse.add(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.i(LOG_TAG, "–> Full response was: " + fullResponse);
|
||||
return fullResponse;
|
||||
}
|
||||
|
||||
public static synchronized boolean checkGetRootAuth() {
|
||||
Process process = null;
|
||||
DataOutputStream os = null;
|
||||
try {
|
||||
Log.i(LOG_TAG, "to exec su");
|
||||
process = Runtime.getRuntime().exec("su");
|
||||
os = new DataOutputStream(process.getOutputStream());
|
||||
os.writeBytes("exit\n");
|
||||
os.flush();
|
||||
int exitValue = process.waitFor();
|
||||
Log.i(LOG_TAG, "exitValue=" + exitValue);
|
||||
if (exitValue == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.i(LOG_TAG, "Unexpected error - Here is what I know: "
|
||||
+ e.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
process.destroy();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized boolean checkBusybox() {
|
||||
try {
|
||||
Log.i(LOG_TAG, "to exec busybox df");
|
||||
String[] strCmd = new String[]{"busybox", "df"};
|
||||
ArrayList<String> execResult = executeCommand(strCmd);
|
||||
if (execResult != null) {
|
||||
Log.i(LOG_TAG, "execResult=" + execResult.toString());
|
||||
return true;
|
||||
} else {
|
||||
Log.i(LOG_TAG, "execResult=null");
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.i(LOG_TAG, "Unexpected error - Here is what I know: "
|
||||
+ e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized boolean checkAccessRootData() {
|
||||
try {
|
||||
Log.i(LOG_TAG, "to write /data");
|
||||
String fileContent = "test_ok";
|
||||
Boolean writeFlag = writeFile("/data/su_test", fileContent);
|
||||
if (writeFlag) {
|
||||
Log.i(LOG_TAG, "write ok");
|
||||
} else {
|
||||
Log.i(LOG_TAG, "write failed");
|
||||
}
|
||||
|
||||
Log.i(LOG_TAG, "to read /data");
|
||||
String strRead = readFile("/data/su_test");
|
||||
Log.i(LOG_TAG, "strRead=" + strRead);
|
||||
if (fileContent.equals(strRead)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.i(LOG_TAG, "Unexpected error - Here is what I know: "
|
||||
+ e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Boolean writeFile(String fileName, String message) {
|
||||
try {
|
||||
FileOutputStream fout = new FileOutputStream(fileName);
|
||||
byte[] bytes = message.getBytes();
|
||||
fout.write(bytes);
|
||||
fout.close();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String readFile(String fileName) {
|
||||
File file = new File(fileName);
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] bytes = new byte[1024];
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
int len;
|
||||
while ((len = fis.read(bytes)) > 0) {
|
||||
bos.write(bytes, 0, len);
|
||||
}
|
||||
String result = new String(bos.toByteArray());
|
||||
Log.i(LOG_TAG, result);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user