From 3636ffdc2feaa203629e35920417b030b778da59 Mon Sep 17 00:00:00 2001 From: gallonyin Date: Fri, 9 Dec 2022 16:15:49 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E5=B0=81=E8=A3=85base=E5=BA=93;?= =?UTF-8?q?=E9=9B=86=E6=88=90flowwindow=E5=BA=93;=E6=82=AC=E6=B5=AE?= =?UTF-8?q?=E7=AA=97=E5=8A=9F=E8=83=BD;=E8=B5=9E=E5=8A=A9=E5=92=8C?= =?UTF-8?q?=E5=88=86=E4=BA=AB;=E9=9B=86=E6=88=90=E4=BC=81=E5=BE=AEsdk;?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E6=9B=B4=E6=96=B0;=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=BE=85=E5=8A=9E=E4=BF=AE=E5=A4=8D;=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E6=89=8B=E5=8A=BF=E4=BC=98=E5=8C=96;=E5=BB=BA=E7=BE=A4?= =?UTF-8?q?=E8=BE=BE=E5=88=B0=E4=B8=8A=E9=99=90=E6=A3=80=E6=9F=A5;?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E5=87=8F=E5=8F=B7=E5=92=8C=E6=8B=AC=E5=8F=B7?= =?UTF-8?q?=E6=90=9C=E7=B4=A2;=E5=BA=94=E7=94=A8=E4=BF=9D=E6=B4=BB;?= =?UTF-8?q?=E5=85=B6=E4=BB=96=E5=B7=B2=E7=9F=A5=E7=BC=BA=E9=99=B7=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 29 +- app/libs/lib_wwapi-2.0.12.11.aar | Bin 0 -> 103997 bytes app/src/main/AndroidManifest.xml | 19 + .../java/org/yameida/worktool/Constant.kt | 25 +- .../org/yameida/worktool/MyApplication.kt | 5 +- .../worktool/activity/BrowserActivity.kt | 26 + .../activity/FloatViewGuideActivity.kt | 68 ++ .../worktool/activity/ListenActivity.kt | 61 +- .../worktool/activity/SettingsActivity.kt | 279 +++++++ .../worktool/model/WeworkMessageBean.java | 46 +- .../yameida/worktool/service/GlobalMethod.kt | 18 +- .../org/yameida/worktool/service/MyLooper.kt | 17 +- .../worktool/service/WeworkController.kt | 10 + .../yameida/worktool/service/WeworkGetImpl.kt | 41 + .../worktool/service/WeworkLoopImpl.kt | 78 +- .../worktool/service/WeworkOperationImpl.kt | 40 +- .../yameida/worktool/service/WeworkService.kt | 20 +- .../worktool/utils/AccessibilityUtil.kt | 161 +++- .../org/yameida/worktool/utils/DonateUtil.kt | 33 + .../worktool/utils/FloatWindowHelper.kt | 133 ++++ .../worktool/utils/FlowPermissionHelper.kt | 81 ++ .../org/yameida/worktool/utils/IWWAPIUtil.kt | 74 ++ .../worktool/utils/PermissionHelper.kt | 10 +- .../org/yameida/worktool/utils/RegexHelper.kt | 7 +- .../worktool/utils/ShareCommentsUtil.java | 67 ++ .../worktool/utils/WebSocketManager.java | 25 +- .../yameida/worktool/utils/WeworkRoomUtil.kt | 2 +- .../worktool/utils/envcheck/CheckRoot.java | 11 +- app/src/main/res/layout/activity_browser.xml | 18 + .../main/res/layout/activity_float_guide.xml | 234 ++++++ app/src/main/res/layout/activity_listen.xml | 112 +-- app/src/main/res/layout/activity_settings.xml | 612 +++++++++++++++ app/src/main/res/layout/dialog_input.xml | 37 - app/src/main/res/values/strings.xml | 9 - app/src/main/res/values/styles.xml | 40 + baselibrary/.gitignore | 1 + baselibrary/build.gradle | 67 ++ baselibrary/proguard-rules.pro | 21 + baselibrary/src/main/AndroidManifest.xml | 2 + .../java/base/adapter/RvSimpleAdapter.java | 95 +++ .../main/java/base/adapter/RvViewHolder.java | 59 ++ baselibrary/src/main/res/values/strings.xml | 2 + baselibrary/src/main/res/values/styles.xml | 2 + floatwindow/.gitignore | 1 + floatwindow/build.gradle | 38 + floatwindow/proguard-rules.pro | 21 + floatwindow/src/main/AndroidManifest.xml | 13 + .../yameida/floatwindow/BaseFloatWindow.java | 706 ++++++++++++++++++ .../floatwindow/DefaultFloatService.kt | 192 +++++ .../yameida/floatwindow/FloatWindowManager.kt | 39 + .../listener/FloatWindowListener.kt | 10 + .../floatwindow/listener/OnClickListener.kt | 11 + .../yameida/floatwindow/view/HiderView.java | 118 +++ .../abc_ic_menu_moreoverflow_mtrl_alpha.png | Bin 0 -> 306 bytes .../main/res/drawable-xxhdpi/back_icon.png | Bin 0 -> 1812 bytes .../res/drawable-xxhdpi/bg_float_guide.png | Bin 0 -> 2645 bytes .../res/drawable-xxhdpi/float_icon_home.png | Bin 0 -> 3262 bytes .../res/drawable-xxhdpi/float_icon_pause.png | Bin 0 -> 3082 bytes .../res/drawable-xxhdpi/float_icon_play.png | Bin 0 -> 3733 bytes .../res/drawable-xxhdpi/float_icon_record.png | Bin 0 -> 3301 bytes .../drawable-xxhdpi/float_icon_setting.png | Bin 0 -> 3235 bytes .../res/drawable-xxhdpi/float_icon_stop.png | Bin 0 -> 2819 bytes .../drawable-xxhdpi/settings_directory.png | Bin 0 -> 322 bytes .../main/res/drawable-xxhdpi/settings_fps.png | Bin 0 -> 145 bytes .../main/res/drawable-xxhdpi/settings_hd.png | Bin 0 -> 342 bytes .../main/res/drawable-xxhdpi/settings_hq.png | Bin 0 -> 368 bytes .../res/drawable-xxhdpi/settings_language.png | Bin 0 -> 697 bytes .../res/drawable-xxhdpi/settings_no_pop.png | Bin 0 -> 734 bytes .../drawable-xxhdpi/settings_orientation.png | Bin 0 -> 616 bytes .../res/drawable-xxhdpi/settings_rate_us.png | Bin 0 -> 1971 bytes .../res/drawable-xxhdpi/settings_share.png | Bin 0 -> 663 bytes .../drawable-xxhdpi/tab_settings_check.png | Bin 0 -> 1448 bytes .../res/drawable-xxhdpi/widget_float_hide.png | Bin 0 -> 68325 bytes .../drawable-xxhdpi/widget_guide_finger.png | Bin 0 -> 2940 bytes .../res/drawable-xxhdpi/widget_tip_button.png | Bin 0 -> 14684 bytes .../main/res/drawable/comment_gray_btn.xml | 22 + .../src/main/res/drawable/comment_red_btn.xml | 22 + .../src/main/res/drawable/ic_arrow_back.xml | 9 + .../src/main/res/layout/layout_menu_left.xml | 99 +++ .../src/main/res/layout/layout_menu_logo.xml | 22 + .../src/main/res/layout/layout_menu_right.xml | 94 +++ .../main/res/layout/widget_hiderview_ll.xml | 15 + .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 50004 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 46156 bytes .../src/main/res/values/colors-rec.xml | 16 + floatwindow/src/main/res/values/colors.xml | 10 + floatwindow/src/main/res/values/dimens.xml | 19 + floatwindow/src/main/res/values/strings.xml | 3 + settings.gradle | 3 +- 89 files changed, 3908 insertions(+), 272 deletions(-) create mode 100644 app/libs/lib_wwapi-2.0.12.11.aar create mode 100644 app/src/main/java/org/yameida/worktool/activity/BrowserActivity.kt create mode 100644 app/src/main/java/org/yameida/worktool/activity/FloatViewGuideActivity.kt create mode 100644 app/src/main/java/org/yameida/worktool/activity/SettingsActivity.kt create mode 100644 app/src/main/java/org/yameida/worktool/utils/DonateUtil.kt create mode 100644 app/src/main/java/org/yameida/worktool/utils/FlowPermissionHelper.kt create mode 100644 app/src/main/java/org/yameida/worktool/utils/IWWAPIUtil.kt create mode 100644 app/src/main/java/org/yameida/worktool/utils/ShareCommentsUtil.java create mode 100644 app/src/main/res/layout/activity_browser.xml create mode 100644 app/src/main/res/layout/activity_float_guide.xml create mode 100644 app/src/main/res/layout/activity_settings.xml delete mode 100644 app/src/main/res/layout/dialog_input.xml create mode 100644 baselibrary/.gitignore create mode 100644 baselibrary/build.gradle create mode 100644 baselibrary/proguard-rules.pro create mode 100644 baselibrary/src/main/AndroidManifest.xml create mode 100644 baselibrary/src/main/java/base/adapter/RvSimpleAdapter.java create mode 100644 baselibrary/src/main/java/base/adapter/RvViewHolder.java create mode 100644 baselibrary/src/main/res/values/strings.xml create mode 100644 baselibrary/src/main/res/values/styles.xml create mode 100644 floatwindow/.gitignore create mode 100644 floatwindow/build.gradle create mode 100644 floatwindow/proguard-rules.pro create mode 100644 floatwindow/src/main/AndroidManifest.xml create mode 100644 floatwindow/src/main/java/org/yameida/floatwindow/BaseFloatWindow.java create mode 100644 floatwindow/src/main/java/org/yameida/floatwindow/DefaultFloatService.kt create mode 100644 floatwindow/src/main/java/org/yameida/floatwindow/FloatWindowManager.kt create mode 100644 floatwindow/src/main/java/org/yameida/floatwindow/listener/FloatWindowListener.kt create mode 100644 floatwindow/src/main/java/org/yameida/floatwindow/listener/OnClickListener.kt create mode 100644 floatwindow/src/main/java/org/yameida/floatwindow/view/HiderView.java create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/abc_ic_menu_moreoverflow_mtrl_alpha.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/back_icon.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/bg_float_guide.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/float_icon_home.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/float_icon_pause.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/float_icon_play.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/float_icon_record.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/float_icon_setting.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/float_icon_stop.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_directory.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_fps.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_hd.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_hq.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_language.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_no_pop.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_orientation.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_rate_us.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/settings_share.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/tab_settings_check.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/widget_float_hide.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/widget_guide_finger.png create mode 100644 floatwindow/src/main/res/drawable-xxhdpi/widget_tip_button.png create mode 100644 floatwindow/src/main/res/drawable/comment_gray_btn.xml create mode 100644 floatwindow/src/main/res/drawable/comment_red_btn.xml create mode 100644 floatwindow/src/main/res/drawable/ic_arrow_back.xml create mode 100644 floatwindow/src/main/res/layout/layout_menu_left.xml create mode 100644 floatwindow/src/main/res/layout/layout_menu_logo.xml create mode 100644 floatwindow/src/main/res/layout/layout_menu_right.xml create mode 100644 floatwindow/src/main/res/layout/widget_hiderview_ll.xml create mode 100644 floatwindow/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 floatwindow/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 floatwindow/src/main/res/values/colors-rec.xml create mode 100644 floatwindow/src/main/res/values/colors.xml create mode 100644 floatwindow/src/main/res/values/dimens.xml create mode 100644 floatwindow/src/main/res/values/strings.xml diff --git a/app/build.gradle b/app/build.gradle index 7d4d1d8..5c572cf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,35 +31,12 @@ android { } dependencies { - implementation fileTree(dir: "libs", include: ["*.jar"]) - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' - implementation 'androidx.appcompat:appcompat:1.3.1' - implementation 'com.google.android.material:material:1.4.0' - - //工具集 - implementation 'com.blankj:utilcodex:1.31.0' - //toast - implementation 'com.github.getActivity:ToastUtils:10.5' - //Gson - implementation 'com.google.code.gson:gson:2.8.5' - //网络 - implementation 'com.github.bumptech.glide:okhttp3-integration:4.9.0' - - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' + implementation project(':baselibrary') + implementation project(':floatwindow') + implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"]) //友盟统计SDK implementation 'com.umeng.umsdk:common:9.4.7'// 必选 implementation 'com.umeng.umsdk:asms:1.4.1'// 必选 implementation 'com.umeng.umsdk:apm:1.5.2' // 错误分析升级为独立SDK,看crash数据请一定集成,可选 - - //自动更新 - implementation 'com.teprinciple:updateapputilsx:2.3.0' - //ok - implementation 'com.lzy.net:okgo:3.0.4' - //qrcode - implementation 'com.github.yoojia:next-qrcode:2.0-2' - //QMUI - implementation 'com.qmuiteam:qmui:2.0.0-alpha10' } \ No newline at end of file diff --git a/app/libs/lib_wwapi-2.0.12.11.aar b/app/libs/lib_wwapi-2.0.12.11.aar new file mode 100644 index 0000000000000000000000000000000000000000..5f9a9cc253eb42f4a119bea9c6f278ec36329d71 GIT binary patch literal 103997 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 @@ -44,7 +46,24 @@ + + + + + + + SPUtils.getInstance().put("not_show_float_guide", isChecked) + } + + val alphaAnimation = AlphaAnimation(0.2F, 1F).apply { + duration = 800 + repeatCount = Animation.INFINITE + repeatMode = Animation.REVERSE + } + iv_over_finger.startAnimation(alphaAnimation) + } + + override fun onResume() { + super.onResume() + val canDrawOverlays = Settings.canDrawOverlays(Utils.getApp()) + LogUtils.d("Settings.canDrawOverlays: $canDrawOverlays") + if (canDrawOverlays) { + finish() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/activity/ListenActivity.kt b/app/src/main/java/org/yameida/worktool/activity/ListenActivity.kt index 5987930..38c4e30 100644 --- a/app/src/main/java/org/yameida/worktool/activity/ListenActivity.kt +++ b/app/src/main/java/org/yameida/worktool/activity/ListenActivity.kt @@ -4,14 +4,12 @@ import android.os.Bundle import android.provider.Settings import android.view.WindowManager import android.widget.CompoundButton -import android.widget.Switch import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import com.blankj.utilcode.util.* import com.umeng.analytics.MobclickAgent import kotlinx.android.synthetic.main.activity_listen.* import org.yameida.worktool.* -import org.yameida.worktool.service.WeworkService import android.content.* import android.text.InputType import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -28,7 +26,9 @@ class ListenActivity : AppCompatActivity() { * @param type 0=游客登录 */ fun enterActivity(context: Context, type: Int) { + LogUtils.d("ListenActivity.enterActivity type: $type") context.startActivity(Intent(context, ListenActivity::class.java).apply { + this.flags = Intent.FLAG_ACTIVITY_NEW_TASK putExtra("type", type) }) } @@ -56,10 +56,7 @@ class ListenActivity : AppCompatActivity() { override fun onResume() { super.onResume() sw_overlay.isChecked = PermissionUtils.isGrantedDrawOverlays() - freshOpenServiceSwitch( - WeworkService::class.java, - sw_accessibility - ) + freshOpenServiceSwitch() if (needToWork) { needToWork = false goToWork() @@ -67,28 +64,19 @@ class ListenActivity : AppCompatActivity() { } private fun initView() { - et_channel.setText(SPUtils.getInstance().getString(Constant.LISTEN_CHANNEL_ID)) + iv_settings.setOnClickListener { + SettingsActivity.enterActivity(this) + } + et_channel.setText(Constant.robotId) bt_save.setOnClickListener { val channel = et_channel.text.toString().trim() - SPUtils.getInstance().put(Constant.LISTEN_CHANNEL_ID, channel) + Constant.robotId = channel ToastUtils.showLong("保存成功") sendBroadcast(Intent(Constant.WEWORK_NOTIFY).apply { putExtra("type", "modify_channel") }) MobclickAgent.onProfileSignIn(channel) } - sw_encrypt.isChecked = Constant.encryptType == 1 - sw_encrypt.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked -> - LogUtils.i("sw_encrypt onCheckedChanged: $isChecked") - Constant.encryptType = if (isChecked) 1 else 0 - SPUtils.getInstance().put("encryptType", Constant.encryptType) - }) - sw_auto_reply.isChecked = Constant.autoReply == 1 - sw_auto_reply.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked -> - LogUtils.i("sw_auto_reply onCheckedChanged: $isChecked") - Constant.autoReply = if (isChecked) 1 else 0 - SPUtils.getInstance().put("autoReply", Constant.autoReply) - }) tv_host.text = Constant.host tv_host.setOnClickListener { showSelectHostDialog() @@ -134,7 +122,7 @@ class ListenActivity : AppCompatActivity() { sw_accessibility.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked -> LogUtils.i("sw_accessibility onCheckedChanged: $isChecked") if (isChecked) { - if (SPUtils.getInstance().getString(Constant.LISTEN_CHANNEL_ID).isNullOrBlank()) { + if (Constant.robotId.isBlank()) { sw_accessibility.isChecked = false ToastUtils.showLong("请先填写并保存链接号~") } else if (!PermissionHelper.isAccessibilitySettingOn()) { @@ -183,24 +171,15 @@ class ListenActivity : AppCompatActivity() { private fun openAccessibility() { val clickListener = DialogInterface.OnClickListener { dialog, which -> - freshOpenServiceSwitch( - WeworkService::class.java, - sw_accessibility - ) + freshOpenServiceSwitch() val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS) startActivity(intent) } val cancel = DialogInterface.OnCancelListener { - freshOpenServiceSwitch( - WeworkService::class.java, - sw_accessibility - ) + freshOpenServiceSwitch() } val cancelListener = DialogInterface.OnClickListener { dialog, which -> - freshOpenServiceSwitch( - WeworkService::class.java, - sw_accessibility - ) + freshOpenServiceSwitch() } val dialog: AlertDialog = AlertDialog.Builder(this) .setMessage(R.string.tips) @@ -211,20 +190,8 @@ class ListenActivity : AppCompatActivity() { dialog.show() } - private fun freshOpenServiceSwitch(clazz: Class<*>, s: Switch) { - if (PermissionHelper.isAccessibilitySettingOn()) { - s.isChecked = true - when (s.id) { - R.id.sw_accessibility -> { - } - } - } else { - s.isChecked = false - when (s.id) { - R.id.sw_accessibility -> { - } - } - } + private fun freshOpenServiceSwitch() { + sw_accessibility.isChecked = PermissionHelper.isAccessibilitySettingOn() } private fun showSelectHostDialog() { diff --git a/app/src/main/java/org/yameida/worktool/activity/SettingsActivity.kt b/app/src/main/java/org/yameida/worktool/activity/SettingsActivity.kt new file mode 100644 index 0000000..e00b7da --- /dev/null +++ b/app/src/main/java/org/yameida/worktool/activity/SettingsActivity.kt @@ -0,0 +1,279 @@ +package org.yameida.worktool.activity + +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.os.Bundle +import android.provider.Settings +import android.text.InputType +import android.view.WindowManager +import android.widget.CompoundButton +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import com.blankj.utilcode.util.* +import com.lzy.okgo.OkGo +import com.lzy.okgo.callback.StringCallback +import com.lzy.okgo.model.Response +import com.qmuiteam.qmui.widget.dialog.QMUIDialog +import kotlinx.android.synthetic.main.activity_settings.* +import okhttp3.MediaType +import okhttp3.RequestBody +import org.json.JSONObject +import org.yameida.worktool.Constant +import org.yameida.worktool.R +import org.yameida.worktool.utils.* + + +/** + * 登录页 + */ +class SettingsActivity : AppCompatActivity() { + + companion object { + fun enterActivity(context: Context) { + LogUtils.d("SettingsActivity.enterActivity") + context.startActivity(Intent(context, SettingsActivity::class.java).apply { + this.flags = Intent.FLAG_ACTIVITY_NEW_TASK + }) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + setContentView(R.layout.activity_settings) + + initView() + } + + override fun onResume() { + super.onResume() + freshOpenFlow() + freshOpenMain() + } + + private fun initView() { + iv_back_left.setOnClickListener { finish() } + sw_encrypt.isChecked = Constant.encryptType == 1 + sw_encrypt.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked -> + LogUtils.i("sw_encrypt onCheckedChanged: $isChecked") + Constant.encryptType = if (isChecked) 1 else 0 + SPUtils.getInstance().put("encryptType", Constant.encryptType) + }) + sw_receive.isChecked = Constant.autoReply == 1 + sw_receive.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked -> + LogUtils.i("sw_receive onCheckedChanged: $isChecked") + Constant.autoReply = if (isChecked) 1 else 0 + SPUtils.getInstance().put("autoReply", Constant.autoReply) + }) + rl_reply_strategy.setOnClickListener { showReplyStrategyDialog() } + rl_qa_url.setOnClickListener { showQaUrlDialog() } + rl_donate.setOnClickListener { showDonateDialog() } + rl_share.setOnClickListener { showShareDialog() } + freshOpenFlow() + bt_open_flow.setOnClickListener { + freshOpenFlow() + if (Settings.canDrawOverlays(Utils.getApp())) { + if (!FlowPermissionHelper.canBackgroundStart(Utils.getApp())) { + ToastUtils.showLong("请同时打开后台弹出界面权限~") + PermissionPageManagement.goToSetting(this) + } + FloatWindowHelper.showWindow() + } else { + startActivityForResult(Intent(this, FloatViewGuideActivity::class.java), 0) + } + } + freshOpenMain() + bt_open_main.setOnClickListener { + freshOpenMain() + if (PermissionHelper.isAccessibilitySettingOn()) { + val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS) + startActivity(intent) + } else { + if (Constant.robotId.isBlank()) { + ToastUtils.showLong("请先填写并保存链接号~") + } else if (!PermissionHelper.isAccessibilitySettingOn()) { + openAccessibility() + } + } + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + freshOpenFlow() + if (Settings.canDrawOverlays(Utils.getApp())) { + if (!FlowPermissionHelper.canBackgroundStart(Utils.getApp())) { + ToastUtils.showLong("请同时打开后台弹出界面权限~") + PermissionPageManagement.goToSetting(this) + } + FloatWindowHelper.showWindow() + } + } + + private fun showReplyStrategyDialog() { + val strategyArray = arrayOf("只读消息不回调", "仅私聊和群聊@机器人回调", "私聊群聊全部回调") + QMUIDialog.CheckableDialogBuilder(this) + .setTitle("回复策略") + .addItems(strategyArray) { dialog, which -> + dialog.dismiss() + updateRobotReplyStrategy(which) + } + .setCheckedIndex(Constant.replyStrategy) + .create(R.style.QMUI_Dialog) + .show() + } + + private fun showQaUrlDialog() { + val builder = QMUIDialog.EditTextDialogBuilder(this) + builder.setTitle("消息回调地址") + .setPlaceholder("请输入回调接口地址") + .setDefaultText(Constant.qaUrl) + .setInputType(InputType.TYPE_CLASS_TEXT) + .addAction(getString(R.string.delete)) { dialog, index -> + dialog.dismiss() + updateRobotQaUrl("") + } + .addAction(getString(R.string.cancel)) { dialog, index -> dialog.dismiss() } + .addAction(getString(R.string.add)) { dialog, index -> + val text = builder.editText.text + if (text != null) { + if (text.matches("https?://[^/]+.*".toRegex())) { + dialog.dismiss() + updateRobotQaUrl(text.toString().trim()) + } else { + ToastUtils.showLong("格式异常!") + } + } else { + ToastUtils.showLong("请勿为空!") + } + } + .create(R.style.QMUI_Dialog).show() + } + + private fun showDonateDialog() { + DonateUtil.zfbDonate(this) + } + + private fun showShareDialog() { + startActivity(Intent.createChooser(Intent().apply { + action = Intent.ACTION_SEND + type = ShareUtil.TEXT + putExtra(Intent.EXTRA_TEXT, "我发现一个非常好用的企业微信机器人程序,文档地址: https://worktool.apifox.cn/ APP下载地址是: https://cdn.asrtts.cn/uploads/worktool/apk/worktool-latest.apk") + }, "分享")) + } + + private fun freshOpenFlow() { + if (Settings.canDrawOverlays(Utils.getApp())) { + if (FlowPermissionHelper.canBackgroundStart(Utils.getApp())) { + bt_open_flow.setBackgroundResource(R.drawable.comment_gray_btn) + bt_open_flow.text = "悬浮窗权限已开启" + } else { + bt_open_flow.setBackgroundResource(R.drawable.comment_red_btn) + bt_open_flow.text = "开启后台弹出界面" + } + } else { + bt_open_flow.setBackgroundResource(R.drawable.comment_red_btn) + bt_open_flow.text = "开启悬浮窗权限" + } + } + + private fun freshOpenMain() { + if (PermissionHelper.isAccessibilitySettingOn()) { + bt_open_main.setBackgroundResource(R.drawable.comment_gray_btn) + bt_open_main.text = "主功能已开启" + } else { + bt_open_main.setBackgroundResource(R.drawable.comment_red_btn) + bt_open_main.text = "开启主功能" + } + } + + /** + * 打开辅助 + */ + private fun openAccessibility() { + val clickListener = + DialogInterface.OnClickListener { dialog, which -> + freshOpenMain() + val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS) + startActivity(intent) + } + val cancel = DialogInterface.OnCancelListener { + freshOpenMain() + } + val cancelListener = DialogInterface.OnClickListener { dialog, which -> + freshOpenMain() + } + val dialog: AlertDialog = AlertDialog.Builder(this) + .setMessage(R.string.tips) + .setOnCancelListener(cancel) + .setNegativeButton("取消", cancelListener) + .setPositiveButton("确定", clickListener) + .create() + dialog.show() + } + + private fun updateRobotQaUrl(callbackUrl: String) { + try { + val json = hashMapOf() + json["robotId"] = Constant.robotId + if (callbackUrl.isEmpty()) { + json["openCallback"] = 0 + } else { + json["openCallback"] = 1 + json["callbackUrl"] = callbackUrl + } + val requestBody = RequestBody.create( + MediaType.parse("application/json;charset=UTF-8"), + GsonUtils.toJson(json) + ) + val call = object : StringCallback() { + override fun onSuccess(response: Response?) { + if (response != null && JSONObject(response.body()).getInt("code") == 200) { + Constant.qaUrl = callbackUrl + ToastUtils.showLong(if (callbackUrl.isEmpty()) "关闭成功" else "更新成功") + } else { + onError(response) + } + } + + override fun onError(response: Response?) { + ToastUtils.showLong(if (callbackUrl.isEmpty()) "关闭失败,请稍后再试~" else "更新失败,请稍后再试~") + } + } + OkGo.post(Constant.getRobotUpdateUrl()).upRequestBody(requestBody).execute(call) + } catch (e: Exception) { + throw RuntimeException(e) + } + } + + private fun updateRobotReplyStrategy(type: Int) { + try { + val json = hashMapOf() + json["robotId"] = Constant.robotId + json["replyAll"] = type + val requestBody = RequestBody.create( + MediaType.parse("application/json;charset=UTF-8"), + GsonUtils.toJson(json) + ) + val call = object : StringCallback() { + override fun onSuccess(response: Response?) { + if (response != null && JSONObject(response.body()).getInt("code") == 200) { + Constant.replyStrategy = type + ToastUtils.showLong("更新成功") + } else { + onError(response) + } + } + + override fun onError(response: Response?) { + ToastUtils.showLong("更新失败,请稍后再试~") + } + } + OkGo.post(Constant.getRobotUpdateUrl()).upRequestBody(requestBody).execute(call) + } catch (e: Exception) { + throw RuntimeException(e) + } + } +} diff --git a/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java b/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java index 9136ca3..8ed3cdf 100644 --- a/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java +++ b/app/src/main/java/org/yameida/worktool/model/WeworkMessageBean.java @@ -46,6 +46,7 @@ public class WeworkMessageBean { * 获取群信息 GET_GROUP_INFO * 获取好友信息 GET_FRIEND_INFO * 获取我的信息 GET_MY_INFO + * 获取最近聊天列表 GET_RECENT_LIST */ public static final int HEART_BEAT = 11; public static final int TYPE_RECEIVE_MESSAGE_LIST = 101; @@ -82,6 +83,7 @@ public class WeworkMessageBean { public static final int GET_FRIEND_INFO = 502; public static final int GET_MY_INFO = 503; public static final int GET_GROUP_QRCODE = 504; + public static final int GET_RECENT_LIST = 505; /** * roomType @@ -165,7 +167,7 @@ public class WeworkMessageBean { //转发附加留言 public String extraText; //接收消息类型 - public int textType; + public Integer textType; //群名 public String groupName; @@ -206,7 +208,7 @@ public class WeworkMessageBean { public WeworkMessageBean() {} - public WeworkMessageBean(String receivedName, String receivedContent, int type, Integer roomType, List titleList, List messageList, String log) { + public WeworkMessageBean(String receivedName, String receivedContent, Integer type, Integer roomType, List titleList, List messageList, String log) { this.type = type; this.roomType = roomType; this.titleList = titleList; @@ -217,36 +219,62 @@ public class WeworkMessageBean { } //消息类型 - public int type = 0; + public Integer type = 0; //消息列表的每条消息 public static class SubMessageBean { //0其他人 1机器人自己 2unknown(如系统消息) - public int sender = 0; + public Integer sender; //消息类型判断 仅针对sender=0 - public int textType; + public Integer textType; public List itemMessageList; public List nameList; - public SubMessageBean(int sender, int textType, List itemMessageList, List nameList) { + public SubMessageBean(Integer sender, Integer textType, List itemMessageList, List nameList) { this.sender = sender; this.textType = textType; this.itemMessageList = itemMessageList; this.nameList = nameList; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SubMessageBean that = (SubMessageBean) o; + return Objects.equals(sender, that.sender) && Objects.equals(textType, that.textType) && Objects.equals(itemMessageList, that.itemMessageList) && Objects.equals(nameList, that.nameList); + } + + @Override + public int hashCode() { + return Objects.hash(sender, textType, itemMessageList, nameList); + } } //消息列表每条消息的text推断 public static class ItemMessageBean { //0消息主体上方信息 如日期等 系统消息(拉人/撤回/外部群等居中的提示语) //2消息内容 - public int feature = 0; + public Integer feature; public String text; - public ItemMessageBean(int feature, String text) { + public ItemMessageBean(Integer feature, String text) { this.feature = feature; this.text = text; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ItemMessageBean that = (ItemMessageBean) o; + return Objects.equals(feature, that.feature) && Objects.equals(text, that.text); + } + + @Override + public int hashCode() { + return Objects.hash(feature, text); + } } //我的信息 @@ -315,7 +343,7 @@ public class WeworkMessageBean { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; WeworkMessageBean that = (WeworkMessageBean) o; - return textType == that.textType && showMessageHistory == that.showMessageHistory && type == that.type && Objects.equals(messageId, that.messageId) && Objects.equals(titleList, that.titleList) && Objects.equals(messageList, that.messageList) && Objects.equals(log, that.log) && Objects.equals(roomType, that.roomType) && Objects.equals(receivedName, that.receivedName) && Objects.equals(receivedContent, that.receivedContent) && Objects.equals(at, that.at) && Objects.equals(atList, that.atList) && Objects.equals(originalContent, that.originalContent) && Objects.equals(nameList, that.nameList) && Objects.equals(extraText, that.extraText) && Objects.equals(groupName, that.groupName) && Objects.equals(groupOwner, that.groupOwner) && Objects.equals(selectList, that.selectList) && Objects.equals(groupNumber, that.groupNumber) && Objects.equals(groupAnnouncement, that.groupAnnouncement) && Objects.equals(groupRemark, that.groupRemark) && Objects.equals(groupTemplate, that.groupTemplate) && Objects.equals(newGroupName, that.newGroupName) && Objects.equals(newGroupAnnouncement, that.newGroupAnnouncement) && Objects.equals(removeList, that.removeList) && Objects.equals(myInfo, that.myInfo) && Objects.equals(objectName, that.objectName) && Objects.equals(qrcode, that.qrcode) && Objects.equals(friend, that.friend) && Objects.equals(fileBase64, that.fileBase64) && Objects.equals(fileUrl, that.fileUrl) && Objects.equals(fileType, that.fileType); + return Objects.equals(messageId, that.messageId) && Objects.equals(titleList, that.titleList) && Objects.equals(messageList, that.messageList) && Objects.equals(log, that.log) && Objects.equals(roomType, that.roomType) && Objects.equals(receivedName, that.receivedName) && Objects.equals(receivedContent, that.receivedContent) && Objects.equals(at, that.at) && Objects.equals(atList, that.atList) && Objects.equals(originalContent, that.originalContent) && Objects.equals(nameList, that.nameList) && Objects.equals(extraText, that.extraText) && Objects.equals(textType, that.textType) && Objects.equals(groupName, that.groupName) && Objects.equals(groupOwner, that.groupOwner) && Objects.equals(selectList, that.selectList) && Objects.equals(groupNumber, that.groupNumber) && Objects.equals(groupAnnouncement, that.groupAnnouncement) && Objects.equals(groupRemark, that.groupRemark) && Objects.equals(groupTemplate, that.groupTemplate) && Objects.equals(newGroupName, that.newGroupName) && Objects.equals(newGroupAnnouncement, that.newGroupAnnouncement) && Objects.equals(removeList, that.removeList) && Objects.equals(showMessageHistory, that.showMessageHistory) && Objects.equals(myInfo, that.myInfo) && Objects.equals(objectName, that.objectName) && Objects.equals(qrcode, that.qrcode) && Objects.equals(friend, that.friend) && Objects.equals(fileBase64, that.fileBase64) && Objects.equals(fileUrl, that.fileUrl) && Objects.equals(fileType, that.fileType) && Objects.equals(type, that.type); } @Override diff --git a/app/src/main/java/org/yameida/worktool/service/GlobalMethod.kt b/app/src/main/java/org/yameida/worktool/service/GlobalMethod.kt index ecd7d8d..0fc11d0 100644 --- a/app/src/main/java/org/yameida/worktool/service/GlobalMethod.kt +++ b/app/src/main/java/org/yameida/worktool/service/GlobalMethod.kt @@ -144,12 +144,18 @@ fun backPress() { LogUtils.d("尝试点击确定/我知道了/暂不进入") AccessibilityUtil.performClick(confirm) } else { - LogUtils.d("未找到对话框 点击bar中心") - AccessibilityUtil.performXYClick(WeworkController.weworkService, ScreenUtils.getScreenWidth() / 2F, BarUtils.getStatusBarHeight() * 2F) - sleep(Constant.POP_WINDOW_INTERVAL) - val firstEmptyTextView = AccessibilityUtil.findAllByClazz(getRoot(), Views.TextView).firstOrNull { it.text.isNullOrEmpty() } - if (firstEmptyTextView != null && firstEmptyTextView.isClickable) { - AccessibilityUtil.performClick(firstEmptyTextView) + val stayButton = AccessibilityUtil.findOnceByText(getRoot(true), "关闭应用", "等待", exact = true) + if (stayButton != null) { + LogUtils.d("疑似ANR 尝试点击等待") + AccessibilityUtil.performClick(stayButton) + } else { + LogUtils.d("未找到对话框 点击bar中心") + AccessibilityUtil.performXYClick(WeworkController.weworkService, ScreenUtils.getScreenWidth() / 2F, BarUtils.getStatusBarHeight() * 2F) + sleep(Constant.POP_WINDOW_INTERVAL) + val firstEmptyTextView = AccessibilityUtil.findAllByClazz(getRoot(), Views.TextView).firstOrNull { it.text.isNullOrEmpty() } + if (firstEmptyTextView != null && firstEmptyTextView.isClickable) { + AccessibilityUtil.performClick(firstEmptyTextView) + } } } } diff --git a/app/src/main/java/org/yameida/worktool/service/MyLooper.kt b/app/src/main/java/org/yameida/worktool/service/MyLooper.kt index dda7f88..2f499f6 100644 --- a/app/src/main/java/org/yameida/worktool/service/MyLooper.kt +++ b/app/src/main/java/org/yameida/worktool/service/MyLooper.kt @@ -6,12 +6,14 @@ import android.os.Message import com.blankj.utilcode.util.EncryptUtils import com.blankj.utilcode.util.GsonUtils import com.blankj.utilcode.util.LogUtils +import com.blankj.utilcode.util.SPUtils import com.google.gson.reflect.TypeToken import okhttp3.WebSocket import org.yameida.worktool.Constant import org.yameida.worktool.model.ExecCallbackBean import org.yameida.worktool.model.WeworkMessageBean import org.yameida.worktool.model.WeworkMessageListBean +import org.yameida.worktool.utils.FloatWindowHelper import java.nio.charset.StandardCharsets import java.util.LinkedHashSet import kotlin.concurrent.thread @@ -21,12 +23,16 @@ object MyLooper { private var threadHandler: Handler? = null val looper = thread { - LogUtils.e("myLooper starting...") + LogUtils.i("myLooper starting...") Looper.prepare() val myLooper = Looper.myLooper() if (myLooper != null) { threadHandler = object : Handler(myLooper) { override fun handleMessage(msg: Message) { + while (FloatWindowHelper.isPause) { + LogUtils.i("主功能暂停...") + sleep(Constant.CHANGE_PAGE_INTERVAL) + } LogUtils.d("handle message: " + Thread.currentThread().name, msg) try { dealWithMessage(msg.obj as WeworkMessageBean) @@ -42,7 +48,11 @@ object MyLooper { Looper.loop() } - fun init() {} + fun init() { + LogUtils.i("init myLooper...") + SPUtils.getInstance("noTipMessage").clear() + SPUtils.getInstance("limit").clear() + } fun getInstance(): Handler { while (true) { @@ -168,6 +178,9 @@ object MyLooper { WeworkMessageBean.GET_MY_INFO -> { WeworkController.getMyInfo(message) } + WeworkMessageBean.GET_RECENT_LIST -> { + WeworkController.getRecentList(message) + } WeworkMessageBean.ROBOT_CONTROLLER_TEST -> { WeworkController.test(message) } diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkController.kt b/app/src/main/java/org/yameida/worktool/service/WeworkController.kt index 14ffb43..c2b6334 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkController.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkController.kt @@ -390,4 +390,14 @@ object WeworkController { return WeworkGetImpl.getMyInfo(message) } + /** + * 获取最近聊天列表 + * @see WeworkMessageBean.GET_RECENT_LIST + */ + @RequestMapping + fun getRecentList(message: WeworkMessageBean): Boolean { + LogUtils.d("getRecentList():") + return WeworkGetImpl.getRecentList(message) + } + } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt b/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt index 8be45ea..9119ce9 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkGetImpl.kt @@ -197,4 +197,45 @@ object WeworkGetImpl { backPress() return weworkMessageBean } + + /** + * 获取最近聊天列表 + */ + fun getRecentList(message: WeworkMessageBean): Boolean { + goHome() + AccessibilityUtil.scrollToTop(WeworkController.weworkService, getRoot()) + val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView, Views.ListView, Views.ViewGroup) + if (list != null && list.childCount >= 2) { + val listBriefList = LinkedHashSet() + val onScrollListener = object : AccessibilityUtil.OnScrollListener() { + override fun onScroll(): Boolean { + list.refresh() + for (i in 0 until list.childCount) { + val item = list.getChild(i) + val tempList = arrayListOf() + val tvList = AccessibilityUtil.findAllOnceByClazz(item, Views.TextView).mapNotNull { it.text } + tvList.forEach { tempList.add(WeworkMessageBean.ItemMessageBean(null, it.toString())) } + listBriefList.add(WeworkMessageBean.SubMessageBean(null, null, tempList, null)) + //tvList title/time/content + if (tvList.size == 3) { + //只查看最近一周内的消息 + if (tvList[1].isNotBlank() && !tvList[1].contains("(刚刚)|(分钟前)|(上午)|(下午)|(昨天)|(星期)|(日程)|(会议)".toRegex())) { + return true + } + } + } + return false + } + } + //滚动前先获取一次 + onScrollListener.onScroll() + AccessibilityUtil.scrollToBottom(WeworkController.weworkService, getRoot(), listener = onScrollListener) + LogUtils.d("最近聊天列表", GsonUtils.toJson(listBriefList)) + val weworkMessageBean = WeworkMessageBean() + weworkMessageBean.type = WeworkMessageBean.GET_RECENT_LIST + weworkMessageBean.messageList = listBriefList.toList() + WeworkController.weworkService.webSocketManager.send(weworkMessageBean) + } + return true + } } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt b/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt index 7a13884..16486a4 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkLoopImpl.kt @@ -3,8 +3,8 @@ package org.yameida.worktool.service import android.view.accessibility.AccessibilityNodeInfo import androidx.core.text.isDigitsOnly import com.blankj.utilcode.util.LogUtils +import com.blankj.utilcode.util.SPUtils import org.yameida.worktool.Constant -import org.yameida.worktool.Demo import org.yameida.worktool.model.WeworkMessageBean import org.yameida.worktool.service.WeworkController.mainLoopRunning import org.yameida.worktool.utils.* @@ -141,9 +141,7 @@ object WeworkLoopImpl { if (lastMessage != null) { var tempContent = "" for (itemMessage in lastMessage.itemMessageList) { - if (itemMessage.text.contains("@" + Constant.myName) - || itemMessage.text.isDigitsOnly() - ) { + if (itemMessage.text.contains("@" + Constant.myName)) { tempContent = itemMessage.text } } @@ -235,8 +233,24 @@ object WeworkLoopImpl { } } if (logIndex % 120 == 0) { + //让企微切换页面使APP保持活跃 goHomeTab("通讯录") goHomeTab("消息") + //滚动到顶端查看是否有无提示消息 + AccessibilityUtil.scrollToTop(WeworkController.weworkService, getRoot()) + val listview = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView, Views.ListView, Views.ViewGroup) + if (listview != null && listview.childCount >= 2) { + if (checkNoTipMessage(listview) != 1) { + AccessibilityUtil.scrollToBottom(WeworkController.weworkService, getRoot(), listener = object : AccessibilityUtil.OnScrollListener() { + override fun onScroll(): Boolean { + if (checkNoTipMessage(listview) != 0) { + return true + } + return false + } + }) + } + } } if (!isAtHome()) return true if (logIndex++ % 30 == 0) { @@ -244,15 +258,15 @@ object WeworkLoopImpl { if (logIndex % 120 == 0) log("读取首页聊天列表") } val listview = AccessibilityUtil.findOneByClazz(getRoot(), Views.RecyclerView, Views.ListView, Views.ViewGroup) - if (listview != null) { - if (listview.childCount >= 2) { - if (checkUnreadChatRoom(listview)) { - //进入聊天页 - return true - } + if (listview != null && listview.childCount >= 2) { + if (checkUnreadChatRoom(listview)) { + //如果有红点 点击进入聊天页 + return true + } else if (checkNoTipMessage(listview) == 1) { + //如果发现拉入群聊/修改群名/移出群聊 点击进入聊天页 + return true } else { - LogUtils.e("读取聊天列表失败") - error("读取聊天列表失败") + LogUtils.v("未发现新消息或无提示消息") } } else { LogUtils.e("读取聊天列表失败") @@ -263,7 +277,6 @@ object WeworkLoopImpl { /** * 检查首页-聊天列表是否有未读红点并点击进入 - * 获取红点 */ private fun checkUnreadChatRoom(list: AccessibilityNodeInfo): Boolean { val spotNodeList = arrayListOf() @@ -296,6 +309,45 @@ object WeworkLoopImpl { } } + /** + * 检查首页-聊天列表是否有拉入群聊/修改群名/移出群聊等无提示消息 + * @return -1当前列表不存在一周内消息 0未发现无提示消息 1发现无提示消息 + */ + private fun checkNoTipMessage(list: AccessibilityNodeInfo): Int { + list.refresh() + val listBriefList = arrayListOf>() + for (i in 0 until list.childCount) { + val item = list.getChild(i) + val tvList = AccessibilityUtil.findAllOnceByClazz(item, Views.TextView).mapNotNull { it.text } + listBriefList.add(tvList) + //tvList title/time/content + if (tvList.size == 3) { + //只查看最近一周内的消息 + if (tvList[1].isBlank() || tvList[1].contains("(刚刚)|(分钟前)|(上午)|(下午)|(昨天)|(星期)|(日程)|(会议)".toRegex())) { + if (tvList[2].contains("(移出了群聊)|(邀请你加入了)|(修改群名为)|(此群为外部群)|(加入了外部群)".toRegex())) { + val interval = System.currentTimeMillis() / 1000 - SPUtils.getInstance("noTipMessage").getLong(tvList[0].toString(), 0) + if (interval > 3600) { + LogUtils.i("发现无提示消息: $tvList") + log("发现无提示消息: $tvList") + if (AccessibilityUtil.performClick(item)) { + //进入聊天页 下一步 getChatMessageList + } else { + AccessibilityUtil.clickByNode(WeworkController.weworkService, item) + } + SPUtils.getInstance("noTipMessage").put(tvList[0].toString(), System.currentTimeMillis() / 1000) + return 1 + } else { + LogUtils.v("发现无提示消息: $tvList 消息在 $interval 秒前已被查看") + } + } + } else { + return -1 + } + } + } + return 0 + } + /** * 解析消息列表里的一条消息 */ diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt b/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt index ab05195..d6ac7ed 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkOperationImpl.kt @@ -215,6 +215,10 @@ object WeworkOperationImpl { ): Boolean { val startTime = System.currentTimeMillis() if (!WeworkRoomUtil.isGroupExists(groupName)) { + if (!beforeCreateGroupCheck()) { + uploadCommandResult(message, ExecCallbackBean.ERROR_CREATE_GROUP_LIMIT, "建群达到上限", startTime) + return false + } if (!createGroup()) { uploadCommandResult(message, ExecCallbackBean.ERROR_CREATE_GROUP, "创建群失败", startTime) return false @@ -720,9 +724,13 @@ object WeworkOperationImpl { Views.ImageView ) ) + } else if (AccessibilityUtil.findOnceByText(getRoot(), "该用户不存在") != null) { + LogUtils.e("该用户不存在: ${friend.phone}") + uploadCommandResult(message, ExecCallbackBean.ERROR_TARGET, "该用户不存在: ${friend.phone}", startTime) + return false } if (modifyFriendInfo(friend)) { - if (AccessibilityUtil.findTextAndClick(getRoot(), "添加为联系人")) { + if (AccessibilityUtil.findTextAndClick(getRoot(), "添加为联系人", timeout = 2000)) { LogUtils.d("准备发送好友邀请: ${friend.phone}") if (!friend.leavingMsg.isNullOrEmpty()) { AccessibilityUtil.findTextInput(getRoot(), friend.leavingMsg) @@ -833,7 +841,7 @@ object WeworkOperationImpl { } } if (modifyFriendInfo(friend)) { - if (AccessibilityUtil.findTextAndClick(getRoot(), "添加为联系人")) { + if (AccessibilityUtil.findTextAndClick(getRoot(), "添加为联系人", timeout = 2000)) { LogUtils.d("准备发送好友邀请: ${friend.name}") if (!friend.leavingMsg.isNullOrEmpty()) { AccessibilityUtil.findTextInput(getRoot(), friend.leavingMsg) @@ -906,6 +914,9 @@ object WeworkOperationImpl { ): Boolean { val startTime = System.currentTimeMillis() goHome() + if (AccessibilityUtil.findOnceByText(getRoot(), "日程", exact = true) == null) { + AccessibilityUtil.scrollToTop(WeworkController.weworkService, getRoot()) + } val tvDiaryFlag = AccessibilityUtil.findOneByText(getRoot(), "日程", exact = true) if (tvDiaryFlag != null && (tvDiaryFlag.parent?.childCount == 2 || tvDiaryFlag.parent?.childCount == 3)) { AccessibilityUtil.performClick(tvDiaryFlag) @@ -1141,11 +1152,34 @@ object WeworkOperationImpl { } /** - * 检查是否达到当日建群上限 + * 建群前检查是否达到当日建群上限 + * @return true允许建群 false不允许建群 + */ + private fun beforeCreateGroupCheck(): Boolean { + //有建群权限且最近300秒内发现限制建群 + if (SPUtils.getInstance("limit").getBoolean("canCreateGroup", false)) { + val interval = System.currentTimeMillis() / 1000 - SPUtils.getInstance("limit").getLong("createGroupLimit", 0) + if (interval < 300) { + LogUtils.e("发现达到当日建群上限 请等待${300 - interval}秒后再试!") + return false + } + } + return true + } + + /** + * 建群后检查是否达到当日建群上限 + * @return true达到上限 false为达到上限 */ private fun createGroupLimit(): Boolean { val hasLimit = AccessibilityUtil.findOneByText(getRoot(), "新建群聊功能暂时被限制", "未验证企业", timeout = 2000) + if (hasLimit == null) { + SPUtils.getInstance("limit").put("canCreateGroup", true) + } else if (SPUtils.getInstance("limit").getBoolean("canCreateGroup", false)) { + SPUtils.getInstance("limit").put("createGroupLimit", System.currentTimeMillis() / 1000) + LogUtils.e("发现达到当日建群上限") + } return hasLimit != null } diff --git a/app/src/main/java/org/yameida/worktool/service/WeworkService.kt b/app/src/main/java/org/yameida/worktool/service/WeworkService.kt index 5bfbcae..ade4651 100644 --- a/app/src/main/java/org/yameida/worktool/service/WeworkService.kt +++ b/app/src/main/java/org/yameida/worktool/service/WeworkService.kt @@ -15,6 +15,7 @@ import org.yameida.worktool.Constant import org.yameida.worktool.Demo import org.yameida.worktool.utils.* import java.lang.Exception +import kotlin.concurrent.thread /** * 企业微信辅助服务 @@ -24,6 +25,8 @@ import java.lang.Exception class WeworkService : AccessibilityService() { private val TAG = "WeworkService" lateinit var webSocketManager: WebSocketManager + var currentPackage = "" + var currentClass = "" override fun onServiceConnected() { LogUtils.i("初始化成功") @@ -35,7 +38,7 @@ class WeworkService : AccessibilityService() { //初始化消息处理器 MyLooper.init() //开发者可以在这里添加测试代码 启动时调用一次 - Demo.test(AppUtils.isAppDebug()) + thread { Demo.test(AppUtils.isAppDebug()) } //监听是否修改链接号并重新长连接 registerReceiver(object : BroadcastReceiver() { @@ -62,6 +65,11 @@ class WeworkService : AccessibilityService() { * @param event */ override fun onAccessibilityEvent(event: AccessibilityEvent) { + currentPackage = event.packageName?.toString() ?: "" + val className = event.className?.toString() ?: "" + if (className.contains(currentPackage)) { + currentClass = className + } } override fun onInterrupt() { @@ -83,13 +91,13 @@ class WeworkService : AccessibilityService() { private lateinit var socket: WebSocket override fun onOpen(webSocket: WebSocket, response: Response) { socket = webSocket - Log.e(TAG, "链接建立") - val robotId = SPUtils.getInstance().getString(Constant.LISTEN_CHANNEL_ID, "") + Log.e(TAG, "连接建立") + val robotId = Constant.robotId val appVersion = SPUtils.getInstance().getString("appVersion", "") val workVersion = SPUtils.getInstance().getString("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") + log("连接建立: $robotId appVersion: $appVersion workVersion: $workVersion deviceRooted: $deviceRooted hook: $hook") LogUtils.i("设置自动跳转企业微信") sendBroadcast(true) } @@ -107,7 +115,7 @@ class WeworkService : AccessibilityService() { override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { super.onClosed(webSocket, code, reason) //服务器关闭后 - Log.e(TAG, "链接关闭 $reason") + Log.e(TAG, "连接关闭 $reason") sendBroadcast(false) } @@ -120,7 +128,7 @@ class WeworkService : AccessibilityService() { override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) { //服务器中断 - Log.e(TAG, "链接错误: " + t.toString() + response.toString()) + Log.e(TAG, "连接错误: " + t.toString() + response.toString()) sendBroadcast(false) } diff --git a/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt b/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt index c1dc28a..7e2257a 100644 --- a/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt +++ b/app/src/main/java/org/yameida/worktool/utils/AccessibilityUtil.kt @@ -22,6 +22,7 @@ import org.yameida.worktool.service.WeworkController import android.content.ClipData import android.content.ClipboardManager import android.content.Context +import java.lang.StringBuilder /** @@ -54,11 +55,21 @@ import android.content.Context * performLongClick 对某个节点或父节点进行长按 * performLongClickWithSon 对某个节点或子节点进行长按 * + * 注意:操作均为阻塞式,原则上本工具类所有操作都应在子线程执行 */ object AccessibilityUtil { private const val tag = "AccessibilityUtil" private const val SHORT_INTERVAL = 150L - private const val SCROLL_INTERVAL = 500L + private const val SCROLL_INTERVAL_NATIVE = 500L + private const val SCROLL_INTERVAL = 800L + + /** + * 滚动监听 + * 如果期望停止滚动则在onScroll回调中返回true 否则返回false + */ + abstract class OnScrollListener { + abstract fun onScroll(): Boolean + } //编辑EditView(粘贴 不推荐) fun sendTextForEditText(context: Context, nodeInfo: AccessibilityNodeInfo?, text: String): Boolean { @@ -84,8 +95,13 @@ object AccessibilityUtil { } //寻找第一个文本匹配(关键词)并点击 - fun findTextAndClick(nodeInfo: AccessibilityNodeInfo?, vararg textList: String): Boolean { - val textView = findOneByText(nodeInfo, *textList) ?: return false + fun findTextAndClick(nodeInfo: AccessibilityNodeInfo?, + vararg textList: String, + exact: Boolean = false, + timeout: Long = 5000, + root: Boolean = true + ): Boolean { + val textView = findOneByText(nodeInfo, *textList, exact = exact, timeout = timeout, root = root) ?: return false return performClick(textView) } @@ -117,6 +133,106 @@ object AccessibilityUtil { return false } + //滚动到顶部 + fun scrollToTop( + service: AccessibilityService, + nodeInfo: AccessibilityNodeInfo, + scrollNodeIndex: Int = 0, + tryUseGesture: Boolean = true, + listener: OnScrollListener? = null, + maxRetry: Int = 10 + ): Boolean { + var textChanged = false + var index = 0 + while (index++ < maxRetry) { + val scrollBefore = findAllOnceByClazz(getRoot(), Views.TextView) + performScrollUp(nodeInfo, scrollNodeIndex) + if (scrollBefore == findAllOnceByClazz(getRoot(), Views.TextView)) { + LogUtils.d("已经滚动到顶部") + if (textChanged) { + return true + } else { + break + } + } else { + textChanged = true + LogUtils.v("未滚动到顶部 $index") + } + } + if (tryUseGesture) { + LogUtils.d("未找到可滚动列表 使用手势滚动") + val width = ScreenUtils.getScreenWidth() + val height = ScreenUtils.getScreenHeight() + index = 0 + while (index++ < maxRetry) { + val scrollBefore = findAllOnceByClazz(getRoot(), Views.TextView) + scrollByXY(service, width / 2, (height / 2.2).toInt(), 0, height / 3) + if (scrollBefore == findAllOnceByClazz(getRoot(), Views.TextView)) { + LogUtils.d("已经滚动到顶部") + break + } else { + LogUtils.v("未滚动到顶部 $index") + if (listener != null && listener.onScroll()) { + LogUtils.d("提前终止滚动") + return true + } + } + } + return true + } + return false + } + + //滚动到顶部 + fun scrollToBottom( + service: AccessibilityService, + nodeInfo: AccessibilityNodeInfo, + scrollNodeIndex: Int = 0, + tryUseGesture: Boolean = true, + listener: OnScrollListener? = null, + maxRetry: Int = 10 + ): Boolean { + var textChanged = false + var index = 0 + while (index++ < maxRetry) { + val scrollBefore = findAllOnceByClazz(getRoot(), Views.TextView) + performScrollDown(nodeInfo, scrollNodeIndex) + if (scrollBefore == findAllOnceByClazz(getRoot(), Views.TextView)) { + LogUtils.d("已经滚动到底部") + if (textChanged) { + return true + } else { + break + } + } else { + textChanged = true + LogUtils.v("未滚动到底部 $index") + if (listener != null && listener.onScroll()) { + LogUtils.d("提前终止滚动") + return true + } + } + } + if (tryUseGesture) { + LogUtils.d("未找到可滚动列表 使用手势滚动") + val width = ScreenUtils.getScreenWidth() + val height = ScreenUtils.getScreenHeight() + index = 0 + while (index++ < maxRetry) { + val scrollBefore = findAllOnceByClazz(getRoot(), Views.TextView) + scrollByXY(service, width / 2, (height / 2.2).toInt(), 0, -height / 3) + if (scrollBefore == findAllOnceByClazz(getRoot(), Views.TextView)) { + LogUtils.d("已经滚动到底部") + break + } else { + LogUtils.v("未滚动到底部 $index") + } + } + return true + } + return false + } + //滚动并按文本寻找第一个控件 fun scrollAndFindByText( service: AccessibilityService, @@ -124,6 +240,10 @@ object AccessibilityUtil { vararg textList: String, maxRetry: Int = 3 ): AccessibilityNodeInfo? { + val node = findOnceByText(nodeInfo, *textList) + if (node != null) { + return node + } var index = 0 while (index++ < maxRetry) { performScrollDown(nodeInfo, 0) @@ -146,8 +266,7 @@ object AccessibilityUtil { val height = ScreenUtils.getScreenHeight() index = 0 while (index++ < maxRetry * 2) { - scrollByXY(service, width / 2, height / 2, 0, -height / 2) - sleep(SCROLL_INTERVAL) + scrollByXY(service, width / 2, (height / 2.2).toInt(), 0, -height / 3) val node = findOnceByText(nodeInfo, *textList) if (node != null) { return node @@ -155,8 +274,7 @@ object AccessibilityUtil { } index = 0 while (index++ < maxRetry * 3) { - scrollByXY(service, width / 2, height / 2, 0, height / 2) - sleep(SCROLL_INTERVAL) + scrollByXY(service, width / 2, (height / 2.2).toInt(), 0, height / 3) val node = findOnceByText(nodeInfo, *textList) if (node != null) { return node @@ -299,7 +417,7 @@ object AccessibilityUtil { val canScrollNodeList = findCanScrollNode(node) if (canScrollNodeList.size > index) { canScrollNodeList[index].performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) - sleep(SCROLL_INTERVAL) + sleep(SCROLL_INTERVAL_NATIVE) return true } return false @@ -311,7 +429,7 @@ object AccessibilityUtil { val canScrollNodeList = findCanScrollNode(node) if (canScrollNodeList.size > index) { canScrollNodeList[index].performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) - sleep(SCROLL_INTERVAL) + sleep(SCROLL_INTERVAL_NATIVE) return true } return false @@ -814,22 +932,31 @@ object AccessibilityUtil { node: AccessibilityNodeInfo?, printText: Boolean = true, depth: Int = 0 - ) { - if (node == null) return + ): StringBuilder { + val sb = StringBuilder() + if (node == null) return sb var s = "" for (i in 0 until depth) { s += "---" } - Log.d(tag, "$s depth: $depth className: " + node.className + " isClickable: " + node.isClickable) + val temp = "$s depth: $depth className: " + node.className + " isClickable: " + node.isClickable + Log.d(tag, temp) + sb.append(temp).append("\n") + var text = "" if (printText && node.text != null) { - Log.d(tag, "$s depth: $depth text: " + node.text) + text = "$s depth: $depth text: " + node.text + Log.d(tag, text) + sb.append(text).append("\n") } if (printText && node.contentDescription != null) { - Log.d(tag, "$s depth: $depth desc: " + node.contentDescription) + val desc = "$s depth: $depth desc: " + node.contentDescription + Log.d(tag, desc) + sb.append(desc).append("\n") } for (i in 0 until node.childCount) { - printNodeClazzTree(node.getChild(i), printText, depth + 1) + sb.append(printNodeClazzTree(node.getChild(i), printText, depth + 1)) } + return sb } /** @@ -946,7 +1073,7 @@ object AccessibilityUtil { path.lineTo(x.toFloat() + distanceX, y.toFloat() + distanceY) builder.addStroke(StrokeDescription(path, 0L, 300L)) val gesture = builder.build() - return service.dispatchGesture(gesture, object : GestureResultCallback() { + val dispatchGesture = service.dispatchGesture(gesture, object : GestureResultCallback() { override fun onCompleted(gestureDescription: GestureDescription) { LogUtils.v("scroll ok onCompleted") } @@ -955,5 +1082,7 @@ object AccessibilityUtil { LogUtils.v("scroll ok onCancelled") } }, null) + sleep(SCROLL_INTERVAL) + return dispatchGesture } } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/DonateUtil.kt b/app/src/main/java/org/yameida/worktool/utils/DonateUtil.kt new file mode 100644 index 0000000..d2ed9c9 --- /dev/null +++ b/app/src/main/java/org/yameida/worktool/utils/DonateUtil.kt @@ -0,0 +1,33 @@ +package org.yameida.worktool.utils + +import android.content.Intent +import org.yameida.worktool.R +import android.content.Context +import android.net.Uri +import com.blankj.utilcode.util.ToastUtils +import com.blankj.utilcode.util.Utils +import com.qmuiteam.qmui.widget.dialog.QMUIDialog + +object DonateUtil { + + fun zfbDonate(context: Context) { + try { + QMUIDialog.MessageDialogBuilder(context) + .setTitle(context.getString(R.string.host_list)) + .setTitle("捐赠") + .setMessage("如果你觉得${context.getString(R.string.app_name)}很棒,可否愿意花一点点钱请作者喝杯咖啡") + .addAction("支付宝") { + dialog, index -> dialog.dismiss() + ToastUtils.showLong(Utils.getApp().getString(R.string.app_name) + " 因为有你的支持而能够不断更新、完善,非常感谢支持!") + val intent = Intent(Intent.ACTION_VIEW) + intent.data = Uri.parse("alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%3A%2F%2Fqr.alipay.com%2Ffkx15436xnv3mzpuufhvn52%3F_s%3Dweb-other") + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(intent) + } + .create(R.style.QMUI_Dialog) + .show() + } catch (e: Throwable) { + ToastUtils.showShort("打开支付宝失败,你可能还没有安装支付宝客户端") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/FloatWindowHelper.kt b/app/src/main/java/org/yameida/worktool/utils/FloatWindowHelper.kt index e5cb8c8..26b643a 100644 --- a/app/src/main/java/org/yameida/worktool/utils/FloatWindowHelper.kt +++ b/app/src/main/java/org/yameida/worktool/utils/FloatWindowHelper.kt @@ -1,12 +1,145 @@ package org.yameida.worktool.utils +import android.accessibilityservice.AccessibilityService +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection +import android.os.IBinder +import android.os.Message +import android.view.View +import android.widget.ImageView +import com.blankj.utilcode.util.FileUtils import com.blankj.utilcode.util.LogUtils +import com.blankj.utilcode.util.ToastUtils +import com.blankj.utilcode.util.Utils +import com.bumptech.glide.Glide +import org.yameida.floatwindow.FloatWindowManager +import org.yameida.floatwindow.DefaultFloatService +import org.yameida.floatwindow.listener.OnClickListener +import org.yameida.worktool.R +import org.yameida.worktool.activity.ListenActivity +import org.yameida.worktool.activity.SettingsActivity +import org.yameida.worktool.model.WeworkMessageBean +import org.yameida.worktool.service.* +import java.io.File +import java.text.SimpleDateFormat +import java.util.* +import kotlin.concurrent.thread object FloatWindowHelper { + var isPause = false + fun showWindow() { LogUtils.d("FloatWindowHelper.showWindow()") + FloatWindowManager.show(DefaultFloatService::class.java) + + val app = Utils.getApp() + val intent = Intent(app, DefaultFloatService::class.java) + app.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) + } + + /** + * 主功能继续 + */ + private fun accessibilityServiceResume() { + if (PermissionHelper.isAccessibilitySettingOn()) { + LogUtils.i("主功能继续") + ToastUtils.showShort("主功能继续~") + //隐藏软键盘模式 + WeworkController.weworkService.softKeyboardController.showMode = AccessibilityService.SHOW_MODE_HIDDEN + isPause = false + MyLooper.getInstance().removeMessages(WeworkMessageBean.LOOP_RECEIVE_NEW_MESSAGE) + MyLooper.getInstance().sendMessage(Message.obtain().apply { + what = WeworkMessageBean.LOOP_RECEIVE_NEW_MESSAGE + obj = WeworkMessageBean().apply { type = WeworkMessageBean.LOOP_RECEIVE_NEW_MESSAGE } + }) + } else { + LogUtils.e("请先打开WorkTool主功能~") + } + } + + /** + * 主功能暂停 + */ + private fun accessibilityServicePause() { + if (PermissionHelper.isAccessibilitySettingOn()) { + LogUtils.i("主功能暂停") + ToastUtils.showShort("主功能暂停~") + //显示软键盘模式 + WeworkController.weworkService.softKeyboardController.showMode = AccessibilityService.SHOW_MODE_AUTO + isPause = true + WeworkController.mainLoopRunning = false + } else { + LogUtils.e("请先打开WorkTool主功能~") + } + } + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + LogUtils.i("DefaultFloatService 服务连接") + val service = (iBinder as DefaultFloatService.DefaultFloatServiceBinder).getService() + service.onClickListener = object : OnClickListener { + override fun onClick(v: View, event: Int) { + when (event) { + 1 -> { + if (PermissionHelper.isAccessibilitySettingOn()) { + if (!isPause) { + ToastUtils.showShort("请先暂停WorkTool主功能~") + return + } + thread { + val printNodeClazzTree = + AccessibilityUtil.printNodeClazzTree(getRoot(true)) + val df = SimpleDateFormat("MMdd_HHmmss") + val filePath = "${ + Utils.getApp().getExternalFilesDir("share") + }/${df.format(Date())}/${df.format(Date())}_printNode.txt" + val newFile = File(filePath) + val create = FileUtils.createFileByDeleteOldFile(newFile) + if (create && newFile.canWrite()) { + printNodeClazzTree.append("\n") + .append(WeworkController.weworkService.currentPackage) + .append("\n") + .append(WeworkController.weworkService.currentClass) + newFile.writeBytes(printNodeClazzTree.toString().toByteArray()) + LogUtils.i("打印节点文件存储本地成功 $filePath") + } + ShareUtil.share("*", newFile) + } + } else { + ToastUtils.showShort("请先打开WorkTool主功能~") + } + } + 2 -> { + if (PermissionHelper.isAccessibilitySettingOn()) { + if (isPause) { + Glide.with(Utils.getApp()).load(R.drawable.float_icon_pause).into(v as ImageView) + accessibilityServiceResume() + } else { + Glide.with(Utils.getApp()).load(R.drawable.float_icon_play).into(v as ImageView) + accessibilityServicePause() + } + } else { + ToastUtils.showShort("请先打开WorkTool主功能~") + } + } + 3 -> { + ListenActivity.enterActivity(Utils.getApp(), 0) + } + 4 -> { + SettingsActivity.enterActivity(Utils.getApp()) + } + } + } + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + LogUtils.i("DefaultFloatService 服务断开") + } } } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/FlowPermissionHelper.kt b/app/src/main/java/org/yameida/worktool/utils/FlowPermissionHelper.kt new file mode 100644 index 0000000..9a070ce --- /dev/null +++ b/app/src/main/java/org/yameida/worktool/utils/FlowPermissionHelper.kt @@ -0,0 +1,81 @@ +package org.yameida.worktool.utils + +import android.app.AppOpsManager +import android.content.Context +import android.net.Uri +import android.os.Build +import android.provider.Settings +import java.lang.reflect.Method + +object FlowPermissionHelper { + + fun isXiaoMi(): Boolean { + return checkManufacturer("xiaomi") + } + + fun isOppo(): Boolean { + return checkManufacturer("oppo") + } + + fun isVivo(): Boolean { + return checkManufacturer("vivo") + } + + private fun checkManufacturer(manufacturer: String): Boolean { + return manufacturer.equals(Build.MANUFACTURER, true) + } + + fun canBackgroundStart(context: Context): Boolean { + if (isXiaoMi()) { + return isXiaomiBgStartPermissionAllowed(context) + } + + if (isVivo()) { + return isVivoBgStartPermissionAllowed(context) + } + + if (isOppo() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return Settings.canDrawOverlays(context) + } + return true + } + + + private fun isXiaomiBgStartPermissionAllowed(context: Context): Boolean { + val ops = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager + try { + val op = 10021 + val method: Method = ops.javaClass.getMethod("checkOpNoThrow", Int::class.javaPrimitiveType, Int::class.javaPrimitiveType, String::class.java) + val result = method.invoke(ops, op, android.os.Process.myUid(), context.packageName) as Int + return result == AppOpsManager.MODE_ALLOWED + } catch (e: Exception) { + e.printStackTrace() + } + return false + } + + private fun isVivoBgStartPermissionAllowed(context: Context): Boolean { + return getVivoBgStartPermissionStatus(context) == 0 + } + + /** + * 判断Vivo后台弹出界面状态, 1无权限,0有权限 + * @param context context + */ + private fun getVivoBgStartPermissionStatus(context: Context): Int { + val uri: Uri = Uri.parse("content://com.vivo.permissionmanager.provider.permission/start_bg_activity") + val selection = "pkgname = ?" + val selectionArgs = arrayOf(context.packageName) + var state = 1 + try { + context.contentResolver.query(uri, null, selection, selectionArgs, null)?.use { + if (it.moveToFirst()) { + state = it.getInt(it.getColumnIndex("currentstate")) + } + } + } catch (e: Exception) { + e.printStackTrace() + } + return state + } +} diff --git a/app/src/main/java/org/yameida/worktool/utils/IWWAPIUtil.kt b/app/src/main/java/org/yameida/worktool/utils/IWWAPIUtil.kt new file mode 100644 index 0000000..72490a0 --- /dev/null +++ b/app/src/main/java/org/yameida/worktool/utils/IWWAPIUtil.kt @@ -0,0 +1,74 @@ +package org.yameida.worktool.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.BitmapDrawable +import android.widget.Toast +import com.blankj.utilcode.util.AppUtils +import com.blankj.utilcode.util.Utils +import com.tencent.wework.api.IWWAPI +import com.tencent.wework.api.WWAPIFactory +import com.tencent.wework.api.model.WWMediaLink +import com.tencent.wework.api.model.WWMediaMiniProgram +import com.tencent.wework.api.model.WWSimpleRespMessage + + +object IWWAPIUtil { + + private var iwwapi: IWWAPI? = null + + var appid = "wwe51e5ed82702b49b" //企业唯一标识。创建企业后显示在,我的企业 CorpID字段 + var agentid = "1000002" //应用唯一标识。显示在具体应用下的 AgentId字段 + var schema = "wwauthe51e5ed82702b49b000002" + + fun init(context: Context, schema: String = this.schema) { + this.schema = schema + iwwapi = WWAPIFactory.createWWAPI(context) + iwwapi?.registerApp(schema) + } + + fun sendLink(thumbUrl: String?, webpageUrl: String?, title: String?, description: String?) { + val link = WWMediaLink() + link.thumbUrl = thumbUrl + link.webpageUrl = webpageUrl + link.title = title + link.description = description + link.appPkg = AppUtils.getAppPackageName() + link.appName = AppUtils.getAppName() + link.appId = appid + link.agentId = agentid + iwwapi?.sendMessage(link) + } + + fun sendMicroProgram() { + val miniProgram = WWMediaMiniProgram() + miniProgram.appPkg = AppUtils.getAppPackageName() + miniProgram.appName = AppUtils.getAppName() + miniProgram.appId = appid + miniProgram.agentId = agentid + miniProgram.schema = schema + miniProgram.username = "gh_dde54cb88ce7@app" //必须是应用关联的小程序,注意要有@app后缀 + miniProgram.description = "dddddd" + miniProgram.path = "/pages/plugin/index.html?plugid=1cbd3b7c8674e61769436b5e354ddb2f" +// val bitmap = (getDrawable(R.drawable.test) as BitmapDrawable).bitmap +// val stream = ByteArrayOutputStream() +// bitmap.compress(Bitmap.CompressFormat.JPEG, 0, stream) +// val byteArray: ByteArray = stream.toByteArray() + +// miniProgram.hdImageData = byteArray + miniProgram.title = "测试_MaHow" + iwwapi!!.sendMessage(miniProgram) { resp -> + if (resp is WWSimpleRespMessage) { + val rsp = resp as WWSimpleRespMessage + var t: String? = "" + Toast.makeText( + Utils.getApp(), + "发小程序," + rsp.errCode + "," + rsp.errMsg.also { + t = it + }, + Toast.LENGTH_LONG + ).show() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/PermissionHelper.kt b/app/src/main/java/org/yameida/worktool/utils/PermissionHelper.kt index 92cb395..b568a2f 100644 --- a/app/src/main/java/org/yameida/worktool/utils/PermissionHelper.kt +++ b/app/src/main/java/org/yameida/worktool/utils/PermissionHelper.kt @@ -17,7 +17,6 @@ object PermissionHelper { val canonicalName = WeworkService::class.java.canonicalName ?: "" val serviceName = context.packageName + "/" + canonicalName val serviceShortName = context.packageName + "/" + canonicalName.replace(context.packageName, "") - LogUtils.i("isAccessibilitySettingOn: $serviceName $serviceShortName") try { enable = Settings.Secure.getInt( context.contentResolver, @@ -27,6 +26,7 @@ object PermissionHelper { } catch (e: Exception) { e.printStackTrace() } + var flag = false if (enable == 1) { val stringSplitter = TextUtils.SimpleStringSplitter(':') val settingVal = Settings.Secure.getString( @@ -38,14 +38,14 @@ object PermissionHelper { while (stringSplitter.hasNext()) { val accessibilityService = stringSplitter.next() if (accessibilityService == serviceName || accessibilityService == serviceShortName) { - LogUtils.i("isAccessibilitySettingOn: true") - return true + flag = true + break } } } } - LogUtils.i("isAccessibilitySettingOn: false") - return false + LogUtils.v("isAccessibilitySettingOn: $serviceName $serviceShortName $flag") + return flag } } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/RegexHelper.kt b/app/src/main/java/org/yameida/worktool/utils/RegexHelper.kt index cdeec4f..fb82606 100644 --- a/app/src/main/java/org/yameida/worktool/utils/RegexHelper.kt +++ b/app/src/main/java/org/yameida/worktool/utils/RegexHelper.kt @@ -15,9 +15,10 @@ object RegexHelper { .replace("{", "\\{") .replace("}", "\\}") .replace("|", "\\|") -// .replace("-", "\\-") //企微自身限制 -// .replace("(", "\\(") //企微自身限制 -// .replace(")", "\\)") //企微自身限制 + //企微自身存在限制 + .replace("-", "\\-") + .replace("(", "\\(") + .replace(")", "\\)") } } \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/ShareCommentsUtil.java b/app/src/main/java/org/yameida/worktool/utils/ShareCommentsUtil.java new file mode 100644 index 0000000..ab8c783 --- /dev/null +++ b/app/src/main/java/org/yameida/worktool/utils/ShareCommentsUtil.java @@ -0,0 +1,67 @@ +package org.yameida.worktool.utils; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.net.Uri; +import android.os.Environment; + +import com.blankj.utilcode.util.ToastUtils; + +import org.yameida.worktool.R; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.util.ArrayList; + +public class ShareCommentsUtil { + private static boolean checkInstallation(Context context, String packageName) { + try { + context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_ACTIVITIES); + return true; + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + + public static void shareToWeChat(Context context) { + try { + if (!checkInstallation(context, "com.tencent.mm")) { + ToastUtils.showShort("未发现微信"); + return; + } + Intent intent = new Intent(); //分享精确到微信的页面,朋友圈页面,或者选择好友分享页面 + ComponentName comp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareToTimeLineUI"); + intent.setComponent(comp); + intent.setAction(Intent.ACTION_SEND_MULTIPLE); + intent.setType("image/*"); // intent.setType("text/plain");添加Uri图片地址 + String msg = "我想分享"; + intent.putExtra("Kdescription", msg); + ArrayList imageUris = new ArrayList(); + File dir = context.getExternalFilesDir(null); + if (dir == null || dir.getAbsolutePath().equals("")) { + dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()); + } + File pic = new File(dir, "bigbang.jpg"); + pic.deleteOnExit(); + BitmapDrawable bitmapDrawable; + bitmapDrawable = (BitmapDrawable) context.getDrawable(R.mipmap.ic_launcher); + try { + bitmapDrawable.getBitmap().compress(Bitmap.CompressFormat.JPEG, 75, new FileOutputStream(pic)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + Uri uri = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(context.getContentResolver(), pic.getAbsolutePath(), "bigbang.jpg", null)); + imageUris.add(uri); + intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); + ((Activity) context).startActivityForResult(intent, 1000); + } catch (Throwable e) { + ToastUtils.showShort("分享到微信失败"); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java b/app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java index a1baec0..e9e355c 100644 --- a/app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java +++ b/app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java @@ -37,6 +37,7 @@ public class WebSocketManager { private String url; private WebSocketListener listener; private boolean connecting = false; + private long lastConnectedTime = 0L; public WebSocketManager(String url, WebSocketListener listener) { Log.e(url, "新建链接"); @@ -113,18 +114,25 @@ public class WebSocketManager { Log.e(url, "重连"); boolean isConnect = false; int interval = reconnectInt; - while (!isConnect) { + while (true) { try { isConnect = connect(); - Thread.sleep(interval); - if (interval < 600000) { - interval *= 2; + if (isConnect) { + connecting = false; + break; } } catch (Exception e) { e.printStackTrace(); } + try { + Thread.sleep(interval); + if (interval < 600000) { + interval *= 2; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } } - connecting = false; } private boolean connect() { @@ -137,6 +145,7 @@ public class WebSocketManager { } private ScheduledFuture heartCheckStart() { + lastConnectedTime = System.currentTimeMillis(); Runnable r = () -> { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 Log.e(url, "心跳检测" + df.format(new Date()));// new Date()为获取当前系统时间 @@ -145,8 +154,12 @@ public class WebSocketManager { WeworkController.INSTANCE.setEnableLoopRunning(false); //断开链接后进入重连 reConnect(); + //重连后刷新连接时间 + lastConnectedTime = System.currentTimeMillis(); + } + if (System.currentTimeMillis() - lastConnectedTime > heartBeatRate * 2000 && !FloatWindowHelper.INSTANCE.isPause()) { + ToastUtils.show("机器人运行中 请勿人工操作手机~"); } -// ToastUtils.show("机器人运行中 请勿人工操作手机~"); }; //每heartBeatRate秒发一次心跳包 diff --git a/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt b/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt index 4e28d03..e9b1633 100644 --- a/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt +++ b/app/src/main/java/org/yameida/worktool/utils/WeworkRoomUtil.kt @@ -19,7 +19,7 @@ object WeworkRoomUtil { * @see WeworkMessageBean.ROOM_TYPE */ fun getRoomType(print: Boolean = true): Int { - val roomTitle = getRoomTitle(noCut = true) + val roomTitle = getRoomTitle(noCut = true, print = false) when { isExternalSingleChat(roomTitle) -> { LogUtils.d("ROOM_TYPE: ROOM_TYPE_EXTERNAL_CONTACT") diff --git a/app/src/main/java/org/yameida/worktool/utils/envcheck/CheckRoot.java b/app/src/main/java/org/yameida/worktool/utils/envcheck/CheckRoot.java index af03372..b87a097 100644 --- a/app/src/main/java/org/yameida/worktool/utils/envcheck/CheckRoot.java +++ b/app/src/main/java/org/yameida/worktool/utils/envcheck/CheckRoot.java @@ -104,7 +104,7 @@ public class CheckRoot { fullResponse.add(line); } } catch (Exception e) { - e.printStackTrace(); + Log.i(LOG_TAG, "Unexpected error - Here is what I know: " + e.getMessage()); } Log.i(LOG_TAG, "–> Full response was: " + fullResponse); return fullResponse; @@ -137,7 +137,7 @@ public class CheckRoot { } process.destroy(); } catch (Exception e) { - e.printStackTrace(); + Log.i(LOG_TAG, "Unexpected error - Here is what I know: " + e.getMessage()); } } } @@ -181,8 +181,7 @@ public class CheckRoot { return false; } } catch (Exception e) { - Log.i(LOG_TAG, "Unexpected error - Here is what I know: " - + e.getMessage()); + Log.i(LOG_TAG, "Unexpected error - Here is what I know: " + e.getMessage()); return false; } } @@ -195,7 +194,7 @@ public class CheckRoot { fout.close(); return true; } catch (Exception e) { - e.printStackTrace(); + Log.i(LOG_TAG, "Unexpected error - Here is what I know: " + e.getMessage()); return false; } } @@ -214,7 +213,7 @@ public class CheckRoot { Log.i(LOG_TAG, result); return result; } catch (Exception e) { - e.printStackTrace(); + Log.i(LOG_TAG, "Unexpected error - Here is what I know: " + e.getMessage()); return null; } } diff --git a/app/src/main/res/layout/activity_browser.xml b/app/src/main/res/layout/activity_browser.xml new file mode 100644 index 0000000..50d2f76 --- /dev/null +++ b/app/src/main/res/layout/activity_browser.xml @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/activity_float_guide.xml b/app/src/main/res/layout/activity_float_guide.xml new file mode 100644 index 0000000..57568f6 --- /dev/null +++ b/app/src/main/res/layout/activity_float_guide.xml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_listen.xml b/app/src/main/res/layout/activity_listen.xml index d43d529..eeb8d3c 100644 --- a/app/src/main/res/layout/activity_listen.xml +++ b/app/src/main/res/layout/activity_listen.xml @@ -5,9 +5,46 @@ android:layout_height="match_parent" android:background="@color/background"> + + + + + + + + + + + android:layout_height="match_parent" + android:layout_below="@id/rl_bar"> - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml new file mode 100644 index 0000000..4e18a52 --- /dev/null +++ b/app/src/main/res/layout/activity_settings.xml @@ -0,0 +1,612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +