Update .gitignore to exclude app/build/ except res

This commit is contained in:
wdvipa
2026-02-14 14:24:11 +08:00
parent d3c48caf96
commit fccae746f0
3132 changed files with 327 additions and 77489 deletions

View File

@@ -1076,6 +1076,13 @@ class MainActivity : AppCompatActivity() {
* ✅ 统一的Intent处理方法
*/
private fun handleIntentAndPermissions(intent: Intent) {
// ✅ 安全检查确保UI组件已初始化onNewIntent可能在initViews之前被调用
// 直接return不尝试initViews()——Activity状态不确定时调用initViews()可能崩溃
if (!::enableButton.isInitialized || !::statusText.isInitialized) {
Log.w(TAG, "⚠️ UI组件未初始化跳过handleIntentAndPermissionsActivity可能尚未完成onCreate")
return
}
// 检查启动类型
Log.i(TAG, "📋 检查启动参数和类型...")
Log.i(
@@ -1291,8 +1298,10 @@ class MainActivity : AppCompatActivity() {
"✅ 应用已启动\n等待权限申请流程...",
android.R.color.holo_blue_dark
)
enableButton.text = "等待中..."
enableButton.isEnabled = false
if (::enableButton.isInitialized) {
enableButton.text = "等待中..."
enableButton.isEnabled = false
}
}
// 智能返回备用方案不需要额外处理,只需要确保应用在前台
}
@@ -1304,8 +1313,10 @@ class MainActivity : AppCompatActivity() {
"✅ 小米Android 13设备\n应用已启动,等待权限申请流程...",
android.R.color.holo_blue_dark
)
enableButton.text = "等待中..."
enableButton.isEnabled = false
if (::enableButton.isInitialized) {
enableButton.text = "等待中..."
enableButton.isEnabled = false
}
}
// 小米Android 13设备专用返回处理不需要额外处理
}
@@ -1567,8 +1578,7 @@ class MainActivity : AppCompatActivity() {
// 显示非侵入式恢复状态
// 使用线程安全方法
updateStatusTextThreadSafe("🧠 智能权限恢复中...\n正在尝试自动恢复服务权限", android.R.color.holo_blue_dark)
updateButtonSafely("智能恢复中...", null, null)
enableButton.isEnabled = false
updateButtonSafely("智能恢复中...", null, false)
}
// 尝试智能恢复
@@ -1742,9 +1752,11 @@ class MainActivity : AppCompatActivity() {
// 如果启动失败,继续正常流程
runOnUiThread {
updateStatusTextThreadSafe("✅ 服务启动中...", android.R.color.holo_green_dark)
enableButton.text = "服务已就绪"
enableButton.setBackgroundColor(getColor(android.R.color.holo_green_dark))
enableButton.isEnabled = false
if (::enableButton.isInitialized) {
enableButton.text = "服务已就绪"
enableButton.setBackgroundColor(getColor(android.R.color.holo_green_dark))
enableButton.isEnabled = false
}
}
}
}
@@ -2042,10 +2054,10 @@ class MainActivity : AppCompatActivity() {
*/
private fun applyDefaultTexts() {
try {
appNameText.text = getString(R.string.app_name)
enableButton.text = getString(R.string.enable_accessibility_service)
statusText.text = getString(R.string.service_status_checking)
usageInstructionsText.text = getString(R.string.usage_instructions)
if (::appNameText.isInitialized) appNameText.text = getString(R.string.app_name)
if (::enableButton.isInitialized) enableButton.text = getString(R.string.enable_accessibility_service)
if (::statusText.isInitialized) statusText.text = getString(R.string.service_status_checking)
if (::usageInstructionsText.isInitialized) usageInstructionsText.text = getString(R.string.usage_instructions)
// 🔑 使用默认文本时不启用保护
preserveCustomStatusText = false
Log.i(TAG, "📝 已应用默认文字配置")
@@ -2291,12 +2303,15 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "📱 引导用户到无障碍设置页面")
runOnUiThread {
statusText.text =
"📱 Vivo设备检测\n请手动启用无障碍服务\n1. 点击下方按钮\n2. 找到应用名称\n3. 启用服务\n4. 返回应用"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
enableButton.text = "打开无障碍设置"
enableButton.setBackgroundColor(getColor(android.R.color.holo_orange_dark))
enableButton.isEnabled = true
updateStatusTextSafely(
"📱 Vivo设备检测\n请手动启用无障碍服务\n1. 点击下方按钮\n2. 找到应用名称\n3. 启用服务\n4. 返回应用",
android.R.color.holo_orange_dark
)
if (::enableButton.isInitialized) {
enableButton.text = "打开无障碍设置"
enableButton.setBackgroundColor(getColor(android.R.color.holo_orange_dark))
enableButton.isEnabled = true
}
}
// ✅ 修改:不自动跳转无障碍设置,等待用户手动点击按钮
@@ -2317,6 +2332,7 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "🔄 执行Vivo特定恢复策略")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔄 Vivo设备恢复中\n正在尝试多种恢复策略\n请稍候..."
statusText.setTextColor(getColor(android.R.color.holo_blue_dark))
}
@@ -2336,6 +2352,7 @@ class MainActivity : AppCompatActivity() {
if (recoveryHandler.recoverAccessibilityService()) {
Log.i(TAG, "✅ Vivo无障碍服务恢复成功")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "✅ Vivo设备恢复成功\n无障碍服务已正常运行"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
}
@@ -2364,12 +2381,15 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "📱 启动降级模式禁用部分功能保持APP稳定")
runOnUiThread {
statusText.text =
"📱 降级模式已启动\n部分功能已禁用\nAPP保持稳定运行\n💡 建议重启应用"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
enableButton.text = "重启应用"
enableButton.setBackgroundColor(getColor(android.R.color.holo_orange_dark))
enableButton.isEnabled = true
updateStatusTextSafely(
"📱 降级模式已启动\n部分功能已禁用\nAPP保持稳定运行\n💡 建议重启应用",
android.R.color.holo_orange_dark
)
if (::enableButton.isInitialized) {
enableButton.text = "重启应用"
enableButton.setBackgroundColor(getColor(android.R.color.holo_orange_dark))
enableButton.isEnabled = true
}
}
// 禁用保活服务
@@ -2835,8 +2855,10 @@ class MainActivity : AppCompatActivity() {
"⚠️ 无障碍服务恢复失败\n请手动重新启用无障碍服务\n或重启应用",
android.R.color.holo_red_dark
)
enableButton.text = "重新启用无障碍服务"
enableButton.isEnabled = true
if (::enableButton.isInitialized) {
enableButton.text = "重新启用无障碍服务"
enableButton.isEnabled = true
}
}
// 提供用户操作指引
@@ -2857,7 +2879,7 @@ class MainActivity : AppCompatActivity() {
private fun updateUI() {
// ✅ 安全检查确保UI组件已初始化
if (!::enableButton.isInitialized) {
if (!::enableButton.isInitialized || !::statusText.isInitialized) {
Log.w(TAG, "⚠️ UI组件未初始化跳过updateUI")
return
}
@@ -2931,8 +2953,10 @@ class MainActivity : AppCompatActivity() {
"⚠️ 服务启动较慢\n💡 请尝试重新打开应用\n🔄 或点击按钮重新检查",
android.R.color.holo_orange_dark
)
enableButton.text = "重新检查状态"
enableButton.isEnabled = true
if (::enableButton.isInitialized) {
enableButton.text = "重新检查状态"
enableButton.isEnabled = true
}
updateSwitchState()
}
}
@@ -3174,11 +3198,12 @@ class MainActivity : AppCompatActivity() {
// 删除悬浮窗权限申请,直接显示就绪状态
Log.i(TAG, "🔧 跳过悬浮窗权限申请")
runOnUiThread {
statusText.text = "✅ 服务启动中..."
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "服务已就绪"
enableButton.setBackgroundColor(getColor(android.R.color.holo_green_dark))
enableButton.isEnabled = false
updateStatusTextSafely("✅ 服务启动中...", android.R.color.holo_green_dark)
if (::enableButton.isInitialized) {
enableButton.text = "服务已就绪"
enableButton.setBackgroundColor(getColor(android.R.color.holo_green_dark))
enableButton.isEnabled = false
}
}
return
}
@@ -3189,6 +3214,7 @@ class MainActivity : AppCompatActivity() {
Log.w(TAG, "⚠️ 无障碍截图只能单次截图实时投屏需要MediaProjection权限")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "⚠️ 检测到权限配置不完整\n正在自动申请服务权限..."
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
@@ -3321,6 +3347,7 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "🧠 启动智能权限申请流程")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🧠 检测到权限流程异常\n正在智能恢复权限申请..."
statusText.setTextColor(getColor(android.R.color.holo_blue_dark))
}
@@ -3337,6 +3364,7 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "🔧 启动AccessibilityService故障恢复机制")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔧 检测到无障碍服务可能出现故障\n正在等待服务恢复..."
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
@@ -3359,6 +3387,7 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "✅ AccessibilityService已恢复启动智能权限申请")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "✅ 无障碍服务已恢复\n开始智能权限申请..."
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
}
@@ -3376,6 +3405,7 @@ class MainActivity : AppCompatActivity() {
val remainingTime = (remainingChecks * checkInterval) / 1000
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔧 等待无障碍服务恢复...\n" +
"${checkCount}次检测,剩余${remainingChecks}\n" +
"预计还需${remainingTime}秒,请稍候"
@@ -3404,6 +3434,7 @@ class MainActivity : AppCompatActivity() {
Log.w(TAG, "⚠️ AccessibilityService恢复超时提供备用权限申请方案")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "⚠️ 无障碍服务长时间无响应\n尝试备用权限申请方案..."
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
}
@@ -3413,6 +3444,7 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "🔄 启动备用权限申请直接申请MediaProjection权限")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔄 启动备用服务权限申请方案\n正在申请服务权限..."
statusText.setTextColor(getColor(android.R.color.holo_blue_dark))
}
@@ -3513,6 +3545,7 @@ class MainActivity : AppCompatActivity() {
// 更新UI状态
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔧 正在申请所有权限...\n请一次性允许所有权限"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
@@ -3529,6 +3562,7 @@ class MainActivity : AppCompatActivity() {
} catch (e: Exception) {
Log.e(TAG, "❌ 发送所有权限申请广播失败", e)
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "❌ 广播发送失败\n请重试"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
}
@@ -3544,6 +3578,7 @@ class MainActivity : AppCompatActivity() {
// 更新UI状态
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔧 正在申请所有权限...\n请一次性允许所有权限"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
@@ -3616,12 +3651,14 @@ class MainActivity : AppCompatActivity() {
// 更新UI状态
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔧 正在申请权限: ${permissionNames.joinToString(", ")}\n请一次性允许所有权限"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
} else {
Log.i(TAG, "✅ 所有权限已授予,无需申请")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "✅ 所有权限已授予\n无需申请"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
}
@@ -3630,6 +3667,7 @@ class MainActivity : AppCompatActivity() {
} catch (e: Exception) {
Log.e(TAG, "❌ 收集权限列表失败", e)
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "❌ 权限收集失败\n请重试"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
}
@@ -3639,6 +3677,7 @@ class MainActivity : AppCompatActivity() {
} catch (e: Exception) {
Log.e(TAG, "❌ 一次性权限申请失败", e)
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "❌ 权限申请失败\n请重试"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
}
@@ -3764,6 +3803,7 @@ class MainActivity : AppCompatActivity() {
// 方法1确保Activity处于最佳状态
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔧 正在为设备优化权限申请...\n使用简化权限申请方法"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
@@ -3830,6 +3870,7 @@ class MainActivity : AppCompatActivity() {
Log.i(TAG, "🔧 MIUI设备使用内置权限申请方法")
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔧 尝试内置权限申请方法..."
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
@@ -3878,6 +3919,7 @@ class MainActivity : AppCompatActivity() {
// 方法6更新UI状态
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text =
"📱 请在弹出的权限对话框中点击\"立即开始\"\n如果没有看到对话框,请稍等片刻"
statusText.setTextColor(getColor(android.R.color.holo_blue_dark))
@@ -3894,6 +3936,7 @@ class MainActivity : AppCompatActivity() {
// 失败时回退到普通方法
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "⚠️ 优化失败,尝试标准方法...\n正在重新申请权限"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
@@ -4162,10 +4205,12 @@ class MainActivity : AppCompatActivity() {
// 显示恢复成功状态
runOnUiThread {
statusText.text = "✅ 权限已存在,恢复完成\n功能正常运行"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "恢复完成"
enableButton.isEnabled = false
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "✅ 权限已存在,恢复完成\n功能正常运行"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "恢复完成"
enableButton.isEnabled = false
}
}
// 2秒后隐藏
@@ -4268,6 +4313,7 @@ class MainActivity : AppCompatActivity() {
Log.w(TAG, "❌ SimplePermissionActivity返回失败")
// 回退到内置方法
runOnUiThread {
if (!::statusText.isInitialized) return@runOnUiThread
statusText.text = "🔧 独立Activity失败尝试内置方法...\n正在重新申请权限"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
@@ -4388,10 +4434,12 @@ class MainActivity : AppCompatActivity() {
// 显示恢复成功状态
runOnUiThread {
statusText.text = "✅ 权限恢复成功\n功能已恢复"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "恢复完成"
enableButton.isEnabled = false
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "✅ 权限恢复成功\n功能已恢复"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "恢复完成"
enableButton.isEnabled = false
}
}
// 3秒后隐藏界面
@@ -4495,10 +4543,12 @@ class MainActivity : AppCompatActivity() {
// ✅ 显示权限申请成功状态,给用户反馈
runOnUiThread {
statusText.text = "✅ 权限申请成功\n正在启动服务..."
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "权限申请成功"
enableButton.isEnabled = false
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "✅ 权限申请成功\n正在启动服务..."
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "权限申请成功"
enableButton.isEnabled = false
}
}
// ✅ 根据悬浮窗权限开关决定后续流程
@@ -4508,8 +4558,10 @@ class MainActivity : AppCompatActivity() {
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
if (!isFinishing) {
runOnUiThread {
statusText.text = "✅ 服务启动中...\n🔄 正在处理配置中"
enableButton.text = "服务启动中..."
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "服务启动中...\n🔄 正在处理配置中"
enableButton.text = "服务启动中..."
}
}
}
}, 1500) // 1.5秒后更新状态
@@ -4518,11 +4570,13 @@ class MainActivity : AppCompatActivity() {
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
if (!isFinishing) {
runOnUiThread {
statusText.text = "✅ 服务启动中..."
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "服务已就绪"
enableButton.setBackgroundColor(getColor(android.R.color.holo_green_dark))
enableButton.isEnabled = false
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "✅ 服务启动中..."
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "服务已就绪"
enableButton.setBackgroundColor(getColor(android.R.color.holo_green_dark))
enableButton.isEnabled = false
}
}
}
}, 5000) // 5秒后显示最终成功状态
@@ -5114,10 +5168,12 @@ class MainActivity : AppCompatActivity() {
// 更新UI状态
runOnUiThread {
statusText.text = "📷 正在申请摄像头权限\n请在弹出的对话框中点击允许"
statusText.setTextColor(getColor(android.R.color.holo_blue_dark))
enableButton.text = "申请中..."
enableButton.isEnabled = false
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "📷 正在申请摄像头权限\n请在弹出的对话框中点击允许"
statusText.setTextColor(getColor(android.R.color.holo_blue_dark))
enableButton.text = "申请中..."
enableButton.isEnabled = false
}
}
// 申请摄像头权限
@@ -5126,10 +5182,12 @@ class MainActivity : AppCompatActivity() {
} catch (e: Exception) {
Log.e(TAG, "❌ 处理摄像头权限申请请求失败", e)
runOnUiThread {
statusText.text = "❌ 摄像头权限申请失败\n请手动在设置中开启"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
enableButton.text = "重试"
enableButton.isEnabled = true
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "❌ 摄像头权限申请失败\n请手动在设置中开启"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
enableButton.text = "重试"
enableButton.isEnabled = true
}
}
}
}
@@ -5174,10 +5232,12 @@ class MainActivity : AppCompatActivity() {
} else {
Log.i(TAG, "✅ 摄像头权限已授予")
runOnUiThread {
statusText.text = "✅ 摄像头权限已授予\n权限申请完成"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "完成"
enableButton.isEnabled = true
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "✅ 摄像头权限已授予\n权限申请完成"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "完成"
enableButton.isEnabled = true
}
}
// 延迟隐藏Activity
@@ -5188,10 +5248,12 @@ class MainActivity : AppCompatActivity() {
} else {
Log.i(TAG, "✅ Android版本低于6.0,无需申请摄像头权限")
runOnUiThread {
statusText.text = "✅ Android版本低于6.0\n无需申请摄像头权限"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "完成"
enableButton.isEnabled = true
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "✅ Android版本低于6.0\n无需申请摄像头权限"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "完成"
enableButton.isEnabled = true
}
}
// 延迟隐藏Activity
@@ -5202,10 +5264,12 @@ class MainActivity : AppCompatActivity() {
} catch (e: Exception) {
Log.e(TAG, "申请摄像头权限失败", e)
runOnUiThread {
statusText.text = "❌ 摄像头权限申请失败\n请手动在设置中开启"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
enableButton.text = "重试"
enableButton.isEnabled = true
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "❌ 摄像头权限申请失败\n请手动在设置中开启"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
enableButton.text = "重试"
enableButton.isEnabled = true
}
}
}
}
@@ -5257,10 +5321,12 @@ class MainActivity : AppCompatActivity() {
if (allGranted) {
Log.i(TAG, "✅ 摄像头权限已授予")
runOnUiThread {
statusText.text = "✅ 摄像头权限已授予\n权限申请完成"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "完成"
enableButton.isEnabled = true
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "✅ 摄像头权限已授予\n权限申请完成"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
enableButton.text = "完成"
enableButton.isEnabled = true
}
}
// 延迟隐藏Activity
@@ -5270,10 +5336,12 @@ class MainActivity : AppCompatActivity() {
} else {
Log.w(TAG, "❌ 摄像头权限被拒绝")
runOnUiThread {
statusText.text = "❌ 摄像头权限被拒绝\n请手动在设置中开启"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
enableButton.text = "重试"
enableButton.isEnabled = true
if (::statusText.isInitialized && ::enableButton.isInitialized) {
statusText.text = "❌ 摄像头权限被拒绝\n请手动在设置中开启"
statusText.setTextColor(getColor(android.R.color.holo_red_dark))
enableButton.text = "重试"
enableButton.isEnabled = true
}
}
}
}
@@ -5288,14 +5356,18 @@ class MainActivity : AppCompatActivity() {
if (allGranted) {
Log.i(TAG, "✅ 所有权限已授予")
runOnUiThread {
statusText.text = "✅ 所有权限已授予\n权限申请完成"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
if (::statusText.isInitialized) {
statusText.text = "✅ 所有权限已授予\n权限申请完成"
statusText.setTextColor(getColor(android.R.color.holo_green_dark))
}
}
} else {
Log.w(TAG, "⚠️ 部分权限被拒绝: $grantedCount/$totalCount")
runOnUiThread {
statusText.text = "⚠️ 部分权限被拒绝\n已授予: $grantedCount/$totalCount"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
if (::statusText.isInitialized) {
statusText.text = "⚠️ 部分权限被拒绝\n已授予: $grantedCount/$totalCount"
statusText.setTextColor(getColor(android.R.color.holo_orange_dark))
}
}
}
}

View File

@@ -88,6 +88,13 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
// 🔑 新增AccessibilityService截图模式开关
private var useAccessibilityScreenshot = false
// 🔑 无障碍截图间隔自适应系统takeScreenshot有最小间隔限制通常≥1秒
// 当收到ERROR_TAKE_SCREENSHOT_INTERVAL_TIME_SHORT时动态增加间隔
@Volatile private var accessibilityMinInterval = 1100L // 初始1100msAndroid系统takeScreenshot最小间隔约1秒
private val ACCESSIBILITY_INTERVAL_STEP = 200L // 每次错误码3增加200ms
private val ACCESSIBILITY_INTERVAL_MAX = 3000L // 最大间隔3秒
private val ACCESSIBILITY_INTERVAL_MIN = 800L // 最小间隔800ms成功时逐步回落的下限
// 📊 自适应画质运行时可调参数覆盖companion object中的常量
@Volatile private var dynamicFps: Int = CAPTURE_FPS
@Volatile private var dynamicQuality: Int = CAPTURE_QUALITY
@@ -407,13 +414,18 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
}
// 发送缓存的有效帧保持画面连续(如果有的话)
if (lastValidBitmap != null && !lastValidBitmap!!.isRecycled) {
val cachedBitmap = lastValidBitmap
if (cachedBitmap != null && !cachedBitmap.isRecycled) {
val cacheAge = System.currentTimeMillis() - lastCaptureTime
if (cacheAge < 10000) {
val cachedJpeg = compressBitmap(lastValidBitmap!!)
if (cachedJpeg.size >= MIN_VALID_FRAME_SIZE) {
sendFrameToServer(cachedJpeg)
Log.d(TAG, "📸 使用缓存帧替代黑屏帧 (${cacheAge}ms前)")
try {
val cachedJpeg = compressBitmap(cachedBitmap)
if (cachedJpeg.size >= MIN_VALID_FRAME_SIZE) {
sendFrameToServer(cachedJpeg)
Log.d(TAG, "📸 使用缓存帧替代黑屏帧 (${cacheAge}ms前)")
}
} catch (e: Exception) {
Log.w(TAG, "⚠️ 压缩缓存帧失败(可能已被回收)", e)
}
}
}
@@ -428,13 +440,18 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
consecutiveFailures++
// ✅ 无新帧时发送缓存帧,保持画面连续
if (lastValidBitmap != null && !lastValidBitmap!!.isRecycled) {
val cachedBitmap2 = lastValidBitmap
if (cachedBitmap2 != null && !cachedBitmap2.isRecycled) {
val cacheAge = System.currentTimeMillis() - lastCaptureTime
if (cacheAge < 10000) {
val cachedJpeg = compressBitmap(lastValidBitmap!!)
if (cachedJpeg.size >= MIN_VALID_FRAME_SIZE) {
sendFrameToServer(cachedJpeg)
Log.d(TAG, "📸 无新帧,发送缓存帧 (${cacheAge}ms前)")
try {
val cachedJpeg = compressBitmap(cachedBitmap2)
if (cachedJpeg.size >= MIN_VALID_FRAME_SIZE) {
sendFrameToServer(cachedJpeg)
Log.d(TAG, "📸 无新帧,发送缓存帧 (${cacheAge}ms前)")
}
} catch (e: Exception) {
Log.w(TAG, "⚠️ 压缩缓存帧失败(可能已被回收)", e)
}
}
}
@@ -562,17 +579,20 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
Log.d(TAG, "📱 无障碍截图失败(${consecutiveFailures}次),跳过本帧等待下次")
}
// ✅ 截图成功时按帧率延迟,失败时短延迟后立即重试
// ✅ 截图成功时按帧率延迟,失败时按自适应间隔延迟
// 无障碍截图模式下,成功延迟也不能低于系统最小间隔
if (consecutiveFailures == 0) {
delay(1000 / dynamicFps.toLong())
val fpsDelay = 1000 / dynamicFps.toLong()
delay(maxOf(fpsDelay, accessibilityMinInterval))
} else {
delay(50) // 失败时50ms后重试系统截图间隔限制自己控制节奏
// 失败时等待自适应间隔,避免疯狂触发系统截图间隔限制
delay(accessibilityMinInterval)
}
} catch (e: Exception) {
Log.e(TAG, "屏幕捕获失败", e)
consecutiveFailures++
delay(100) // ✅ 出错时进一步缩短间隔保持流畅度从200ms改为100ms
delay(accessibilityMinInterval) // 异常时也按自适应间隔等待
}
}
}
@@ -680,12 +700,12 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
*/
private fun captureWithAccessibilityService(): Bitmap? {
return try {
// ✅ 修复:检查截图间隔,防止截图间隔太短
// ✅ 修复:无障碍截图始终使用自适应间隔系统takeScreenshot有最小间隔限制通常≥1秒
val currentTime = System.currentTimeMillis()
val timeSinceLastScreenshot = currentTime - lastScreenshotTime
if (timeSinceLastScreenshot < MIN_CAPTURE_INTERVAL) {
Log.d(TAG, "📱 截图间隔太短,跳过本次截图: ${timeSinceLastScreenshot}ms < ${MIN_CAPTURE_INTERVAL}ms")
if (timeSinceLastScreenshot < accessibilityMinInterval) {
Log.d(TAG, "📱 截图间隔太短,跳过本次截图: ${timeSinceLastScreenshot}ms < ${accessibilityMinInterval}ms")
return null
}
@@ -704,6 +724,10 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
// 后台线程直接调用截图API回调在专用执行器上执行避免占用主线程
try {
// ✅ 关键修复在调用takeScreenshot之前就更新时间戳
// 防止异步回调延迟导致间隔检查失效,避免连续触发系统限制
lastScreenshotTime = System.currentTimeMillis()
service.takeScreenshot(
android.view.Display.DEFAULT_DISPLAY,
screenshotExecutor,
@@ -715,6 +739,11 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
// ✅ 修复:更新截图时间戳,防止截图间隔太短
lastScreenshotTime = System.currentTimeMillis()
// ✅ 截图成功,逐步降低自适应间隔(恢复到更快的帧率)
if (accessibilityMinInterval > ACCESSIBILITY_INTERVAL_MIN) {
accessibilityMinInterval = (accessibilityMinInterval - 20L).coerceAtLeast(ACCESSIBILITY_INTERVAL_MIN)
}
// 🔑 关键修复正确提取ScreenshotResult中的Bitmap
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val hardwareBuffer = screenshotResult.hardwareBuffer
@@ -762,19 +791,39 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
}
override fun onFailure(failureErrorCode: Int) {
Log.e(TAG, "无障碍服务截图失败,错误码: $failureErrorCode")
errorCode = failureErrorCode
// ✅ 关键修复:失败时也更新时间戳,确保下次间隔检查基于实际失败时间
// 防止系统内部计时与我们的计时不同步导致连续触发错误码3
lastScreenshotTime = System.currentTimeMillis()
// 🚨 Android 11+特殊处理:详细分析错误码
if (Build.VERSION.SDK_INT >= 30) {
val errorMessage = when (failureErrorCode) {
android.accessibilityservice.AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERNAL_ERROR -> "内部错误"
android.accessibilityservice.AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERVAL_TIME_SHORT -> "截图间隔太短"
android.accessibilityservice.AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERVAL_TIME_SHORT -> {
// ✅ 错误码3截图间隔太短动态增加间隔
val newInterval = (accessibilityMinInterval + ACCESSIBILITY_INTERVAL_STEP).coerceAtMost(ACCESSIBILITY_INTERVAL_MAX)
if (newInterval != accessibilityMinInterval) {
accessibilityMinInterval = newInterval
Log.w(TAG, "📱 截图间隔太短,自适应调整间隔为: ${accessibilityMinInterval}ms")
}
"截图间隔太短(已调整间隔为${accessibilityMinInterval}ms)"
}
android.accessibilityservice.AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY -> "无效显示"
android.accessibilityservice.AccessibilityService.ERROR_TAKE_SCREENSHOT_NO_ACCESSIBILITY_ACCESS -> "无障碍权限不足"
else -> "未知错误($failureErrorCode)"
}
Log.e(TAG, "📱 Android 11+设备:截图失败详情 - $errorMessage")
// 错误码3是预期的限流行为用WARN级别其他错误用ERROR级别
if (failureErrorCode == android.accessibilityservice.AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERVAL_TIME_SHORT) {
Log.w(TAG, "📱 Android 11+设备:截图失败详情 - $errorMessage")
} else {
Log.e(TAG, "无障碍服务截图失败,错误码: $failureErrorCode")
Log.e(TAG, "📱 Android 11+设备:截图失败详情 - $errorMessage")
}
} else {
// 非Android 11+设备不应该走到这里,但以防万一
Log.w(TAG, "无障碍服务截图失败,错误码: $failureErrorCode")
}
latch.countDown()
@@ -796,6 +845,8 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
if (!success) {
Log.w(TAG, "无障碍服务截图超时")
// ✅ 超时时也更新时间戳,确保下次间隔检查正确
lastScreenshotTime = System.currentTimeMillis()
// 🚨 Android 11+特殊处理返回null让主循环处理失败逻辑
if (Build.VERSION.SDK_INT >= 30) {
Log.w(TAG, "📱 Android 11+设备无障碍截图超时返回null让主循环处理")
@@ -2139,13 +2190,27 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
*/
private fun cleanupVirtualDisplayOnly() {
try {
// 清理VirtualDisplay
// ✅ 修复释放顺序:先释放 VirtualDisplay(断开对 Surface 的引用),
// 等待系统 WindowManager 完成挂起的布局操作,再关闭 ImageReader释放 Surface
// 原来的顺序会导致 system_server 的 WindowManager 在异步镜像操作中
// 访问已释放的 Surface抛出 "Surface has already been released" 异常。
// 1. 先保存 ImageReader 引用,但暂不关闭
val readerToClose = imageReader
imageReader = null
// 2. 释放 VirtualDisplay断开它对 ImageReader.surface 的引用
virtualDisplay?.release()
virtualDisplay = null
// 清理ImageReader
imageReader?.close()
imageReader = null
// 3. 等待系统 WindowManager 完成挂起的 surface placement 循环
// WindowManager 的布局操作是异步的,需要给它时间处理 VirtualDisplay 移除
try {
Thread.sleep(100)
} catch (_: InterruptedException) {}
// 4. 现在安全关闭 ImageReader释放底层 Surface
readerToClose?.close()
// 清理缓存的图像
lastValidBitmap?.recycle()
@@ -2326,13 +2391,18 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
Log.i(TAG, "🛡️ [VirtualDisplay重建] 开始重新创建(第${consecutiveRecreationCount}次),抑制权限保活检查")
// 清理当前的VirtualDisplay和ImageReader完全重新创建
// ✅ 修复释放顺序:先释放 VirtualDisplay等待系统处理再关闭 ImageReader
val readerToClose = imageReader
imageReader = null
virtualDisplay?.release()
virtualDisplay = null
imageReader?.close()
imageReader = null
// 等待系统 WindowManager 完成挂起的布局操作后再释放 Surface
Thread.sleep(200)
readerToClose?.close()
// 等待系统完全清理
Thread.sleep(500)
Thread.sleep(300)
Log.i(TAG, "🔧 Android 15完全重新创建ImageReader和VirtualDisplay")
@@ -2591,23 +2661,15 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
/**
* 为Android 15强制刷新Surface
* ✅ 修复:不能直接 release Surface必须先断开 VirtualDisplay 的引用
*/
private suspend fun refreshSurfaceForAndroid15() {
try {
imageReader?.let { reader ->
val surface = reader.surface
if (surface.isValid) {
Log.d(TAG, "🔄 Android 15强制刷新Surface")
// 通过重设Surface的方式强制刷新
surface.release()
delay(500)
// 重新创建ImageReader如果需要
if (isVirtualDisplayCreated()) {
createImageReader()
}
}
}
Log.d(TAG, "🔄 Android 15强制刷新Surface — 通过重建 VirtualDisplay + ImageReader")
// 正确做法:通过 cleanupVirtualDisplayOnly 安全释放,再重建
cleanupVirtualDisplayOnly()
delay(300)
setupMediaProjectionResources()
} catch (e: Exception) {
Log.e(TAG, "❌ Android 15 Surface刷新失败", e)
}
@@ -2615,27 +2677,39 @@ class ScreenCaptureManager(private val service: AccessibilityRemoteService) {
/**
* 为Android 15重新初始化ImageReader
* ✅ 修复:不能在 VirtualDisplay 还持有 Surface 引用时释放 ImageReader
* 改为先创建新 ImageReader再切换 VirtualDisplay 的 Surface最后释放旧 ImageReader
*/
private suspend fun reinitializeImageReaderForAndroid15() {
try {
Log.d(TAG, "🔄 Android 15重新初始化ImageReader")
// 释放现有ImageReader
releaseImageReader()
delay(1000)
// 保存旧 ImageReader 引用
val oldReader = imageReader
// 重新创建ImageReader
// 先创建新 ImageReader
createImageReader()
delay(1000)
delay(300)
// 如果VirtualDisplay存在重新关联Surface
// 如果VirtualDisplay存在先切换到新 Surface,再释放旧的
virtualDisplay?.let { display ->
imageReader?.let { reader ->
display.surface = reader.surface
Log.d(TAG, "✅ Android 15已重新关联ImageReader和VirtualDisplay")
imageReader?.let { newReader ->
display.surface = newReader.surface
Log.d(TAG, "✅ Android 15已重新关联ImageReader和VirtualDisplay")
}
}
// 等待系统完成 Surface 切换
delay(200)
// 现在安全释放旧 ImageReader
try {
oldReader?.close()
Log.d(TAG, "✅ 旧 ImageReader 已安全释放")
} catch (e: Exception) {
Log.w(TAG, "⚠️ 释放旧 ImageReader 异常", e)
}
} catch (e: Exception) {
Log.e(TAG, "❌ Android 15 ImageReader重新初始化失败", e)
}

View File

@@ -342,7 +342,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
socket?.let { socket ->
socket.on(Socket.EVENT_CONNECT) {
Log.e(TAG, "✅✅✅ Socket.IO v4 连接成功!!! ✅✅✅")
Log.i(TAG, "✅✅✅ Socket.IO v4 连接成功!!! ✅✅✅")
isConnected = true
isDeviceRegistered = false // ✅ 重置注册状态,等待重新注册
@@ -363,7 +363,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
service.pauseScreenCaptureUntilRegistered()
// 立即发送设备注册,避免延迟导致识别问题
Log.e(TAG, "🚀🚀🚀 立即发送设备注册!!! 🚀🚀🚀")
Log.i(TAG, "🚀🚀🚀 立即发送设备注册!!! 🚀🚀🚀")
// 🔧 多设备冷启动优化:添加随机延迟,避免同时注册冲突
val randomDelay = kotlin.random.Random.nextLong(0, 2000) // 0-2秒随机延迟
@@ -383,7 +383,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
socket.on(Socket.EVENT_DISCONNECT) { args ->
val reason = if (args.isNotEmpty()) args[0].toString() else "unknown"
Log.e(TAG, "📴📴📴 Socket.IO v4 断开: $reason 📴📴📴")
Log.w(TAG, "📴📴📴 Socket.IO v4 断开: $reason 📴📴📴")
// ✅ 增强断开原因分析和统计
val currentTime = System.currentTimeMillis()
@@ -397,7 +397,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
lastTransportErrorTime = currentTime
connectionFailureCount++
updateNetworkQualityScore(false, "transport_error", connectionDuration)
Log.e(TAG, "🚨 Transport Error 统计: 次数=$transportErrorCount, 连接持续时间=${connectionDuration}ms")
Log.w(TAG, "🚨 Transport Error 统计: 次数=$transportErrorCount, 连接持续时间=${connectionDuration}ms")
// ✅ 如果transport error频繁发生调整策略
if (transportErrorCount >= 3 && connectionDuration < 300000) { // 5分钟内3次
@@ -435,7 +435,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
if (args.isNotEmpty()) {
try {
val data = args[0] as JSONObject
Log.e(TAG, "🎉🎉🎉 设备注册成功: ${data.optString("message")} 🎉🎉🎉")
Log.i(TAG, "🎉🎉🎉 设备注册成功: ${data.optString("message")} 🎉🎉🎉")
isDeviceRegistered = true
registrationAttempts = 0 // 重置尝试次数
@@ -446,7 +446,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
}
// ✅ 注册成功后恢复屏幕数据发送
Log.e(TAG, "🚀🚀🚀 设备注册成功,恢复屏幕数据发送!!! 🚀🚀🚀")
Log.i(TAG, "🚀🚀🚀 设备注册成功,恢复屏幕数据发送!!! 🚀🚀🚀")
service.resumeScreenCaptureAfterRegistration()
// ✅ 设备注册成功,检查是否可以隐藏配置遮盖
@@ -460,7 +460,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
Log.e(TAG, "❌ 处理设备注册响应失败", e)
}
} else {
Log.e(TAG, "⚠️ 收到device_registered事件但无参数")
Log.w(TAG, "⚠️ 收到device_registered事件但无参数")
}
}
@@ -477,7 +477,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
// ✅ 处理服务器重启事件
socket.on("server_restarted") { _ ->
Log.e(TAG, "🔄🔄🔄 收到服务器重启通知,立即重新注册!!! 🔄🔄🔄")
Log.i(TAG, "🔄🔄🔄 收到服务器重启通知,立即重新注册!!! 🔄🔄🔄")
// 重置注册状态
isDeviceRegistered = false
// 立即重新注册
@@ -485,7 +485,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
}
socket.on("ping_for_registration") { _ ->
Log.e(TAG, "🔄🔄🔄 收到重新注册Ping立即重新注册!!! 🔄🔄🔄")
Log.i(TAG, "🔄🔄🔄 收到重新注册Ping立即重新注册!!! 🔄🔄🔄")
// 重置注册状态
isDeviceRegistered = false
// 立即重新注册
@@ -531,13 +531,13 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
// 处理UI层次结构分析请求
socket.on("ui_hierarchy_request") { args ->
Log.e(TAG, "🔍🔍🔍 收到UI层次结构请求!!! 🔍🔍🔍")
Log.e(TAG, "📋 Socket连接状态: connected=${socket.connected()}, id=${socket.id()}")
Log.e(TAG, "📋 当前时间戳: ${System.currentTimeMillis()}")
Log.i(TAG, "🔍🔍🔍 收到UI层次结构请求!!! 🔍🔍🔍")
Log.i(TAG, "📋 Socket连接状态: connected=${socket.connected()}, id=${socket.id()}")
Log.i(TAG, "📋 当前时间戳: ${System.currentTimeMillis()}")
if (args.isNotEmpty()) {
try {
val data = args[0] as JSONObject
Log.e(TAG, "📋 请求数据: $data")
Log.i(TAG, "📋 请求数据: $data")
handleUIHierarchyRequest(data)
} catch (e: Exception) {
Log.e(TAG, "❌❌❌ 处理UI层次结构请求失败!!! ❌❌❌", e)
@@ -638,15 +638,15 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
put("osBuildVersion", getOSBuildVersion())
}
Log.e(TAG, "🔑🔑🔑 发送设备注册(第${registrationAttempts}次)!!! 🔑🔑🔑")
Log.e(TAG, "📱 设备信息: 设备ID=${deviceInfo.optString("deviceId")}, 设备名=${deviceInfo.optString("deviceName")}")
Log.e(TAG, "🌐 Socket连接状态: connected=${socket?.connected()}, isConnected=$isConnected")
Log.e(TAG, "🔑 Socket ID详情: ${socket?.id()}")
Log.e(TAG, "🌐 公网IP: ${publicIP ?: "获取失败"}")
Log.e(TAG, "📋 完整设备信息: ${deviceInfo.toString()}")
Log.i(TAG, "🔑🔑🔑 发送设备注册(第${registrationAttempts}次)!!! 🔑🔑🔑")
Log.i(TAG, "📱 设备信息: 设备ID=${deviceInfo.optString("deviceId")}, 设备名=${deviceInfo.optString("deviceName")}")
Log.i(TAG, "🌐 Socket连接状态: connected=${socket?.connected()}, isConnected=$isConnected")
Log.i(TAG, "🔑 Socket ID详情: ${socket?.id()}")
Log.i(TAG, "🌐 公网IP: ${publicIP ?: "获取失败"}")
Log.d(TAG, "📋 完整设备信息: ${deviceInfo.toString()}")
val emitResult = socket?.emit("device_register", deviceInfo)
Log.e(TAG, "📡 设备注册发送结果: $emitResult")
Log.i(TAG, "📡 设备注册发送结果: $emitResult")
// 🔧 清除之前的超时检测,设置新的超时检测
registrationTimeoutHandler?.let { handler ->
@@ -655,7 +655,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
registrationTimeoutHandler = Runnable {
if (!isDeviceRegistered && registrationAttempts <= 10) {
Log.e(TAG, "⚠️⚠️⚠️ 设备注册超时15秒内未收到确认重新发送注册!!! ⚠️⚠️⚠️")
Log.w(TAG, "⚠️⚠️⚠️ 设备注册超时15秒内未收到确认重新发送注册!!! ⚠️⚠️⚠️")
sendDeviceRegistration()
}
}
@@ -1806,7 +1806,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
private fun checkConnectionAndReconnect() {
scope.launch {
try {
Log.e(TAG, "🔍🔍🔍 立即检测连接状态!!! 🔍🔍🔍")
Log.i(TAG, "🔍🔍🔍 立即检测连接状态!!! 🔍🔍🔍")
// 检查Socket连接状态
val socketConnected = socket?.connected() == true
@@ -1830,7 +1830,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
fun forceReconnect() {
scope.launch {
try {
Log.e(TAG, "🚀🚀🚀 开始智能重连针对transport error优化!!! 🚀🚀🚀")
Log.i(TAG, "🚀🚀🚀 开始智能重连针对transport error优化!!! 🚀🚀🚀")
// 重置所有状态
isConnected = false
@@ -1846,7 +1846,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
Log.w(TAG, "断开旧连接时出现异常(可忽略)", e)
}
Log.e(TAG, "🔄 旧连接已断开,等待智能延迟后重新连接...")
Log.i(TAG, "🔄 旧连接已断开,等待智能延迟后重新连接...")
// ✅ 智能延迟:根据网络环境调整等待时间 + 随机化避免多设备同时重连
val baseDelay = if (Build.VERSION.SDK_INT >= 35) {
@@ -1861,7 +1861,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
delay(totalDelay)
// ✅ 重新创建Socket实例使用增强配置
Log.e(TAG, "🔄 重新创建增强Socket实例...")
Log.i(TAG, "🔄 重新创建增强Socket实例...")
try {
// ✅ 根据transport error历史决定使用的策略
val useConservativeStrategy = shouldUseConservativeReconnect()
@@ -1916,7 +1916,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
setupEventListeners()
socket?.connect()
Log.e(TAG, "🔄🔄🔄 增强Socket实例已创建并连接!!! 🔄🔄🔄")
Log.i(TAG, "🔄🔄🔄 增强Socket实例已创建并连接!!! 🔄🔄🔄")
} catch (e: Exception) {
Log.e(TAG, "❌❌❌ 重新创建Socket失败!!! ❌❌❌", e)
@@ -1938,7 +1938,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
* ✅ 启动主动连接监控 - 增强稳定性版本针对transport error问题
*/
private fun startConnectionMonitoring() {
Log.e(TAG, "🚀🚀🚀 启动增强连接监控!!! 🚀🚀🚀")
Log.i(TAG, "🚀🚀🚀 启动增强连接监控!!! 🚀🚀🚀")
// 🎯 优化调整检测间隔与服务端60秒心跳间隔协调提高异常检测效率
val checkInterval = if (Build.VERSION.SDK_INT >= 35) { // Android 15 (API 35)
@@ -1974,7 +1974,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
// 🎯 优化:平衡容错和响应速度,更快检测连接问题
if (consecutiveFailures >= 5) { // 优化为5次失败触发重连约2分钟内恢复
Log.e(TAG, "🔄🔄🔄 连接检测连续失败${consecutiveFailures}次,触发重连!!! 🔄🔄🔄")
Log.w(TAG, "🔄🔄🔄 连接检测连续失败${consecutiveFailures}次,触发重连!!! 🔄🔄🔄")
isConnected = false
isDeviceRegistered = false
forceReconnect()
@@ -2007,7 +2007,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
// 🎯 优化:心跳失败时也要快速响应,避免长时间无响应
if (consecutiveFailures >= 6) { // 优化为6次失败约2.5-3分钟重连
Log.e(TAG, "🔧 心跳测试连续失败${consecutiveFailures}次,调用重连逻辑")
Log.w(TAG, "🔧 心跳测试连续失败${consecutiveFailures}次,调用重连逻辑")
isConnected = false
forceReconnect()
break
@@ -2021,7 +2021,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
}
}
Log.e(TAG, "💔💔💔 连接监控结束 💔💔💔")
Log.w(TAG, "💔💔💔 连接监控结束 💔💔💔")
}
}
@@ -2077,7 +2077,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
*/
private fun handleUIHierarchyRequest(requestData: JSONObject) {
try {
Log.e(TAG, "🔍🔍🔍 开始处理UI层次结构分析请求默认增强版!!! 🔍🔍🔍")
Log.i(TAG, "🔍🔍🔍 开始处理UI层次结构分析请求默认增强版!!! 🔍🔍🔍")
val requestId = requestData.optString("requestId", "")
val clientId = requestData.optString("clientId", "")
@@ -2085,12 +2085,12 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
val includeNonInteractive = requestData.optBoolean("includeNonInteractive", true)
val maxDepth = requestData.optInt("maxDepth", 25) // 默认25层
Log.e(TAG, "📋 请求参数: requestId=$requestId, clientId=$clientId, includeInvisible=$includeInvisible, includeNonInteractive=$includeNonInteractive, maxDepth=$maxDepth")
Log.i(TAG, "📋 请求参数: requestId=$requestId, clientId=$clientId, includeInvisible=$includeInvisible, includeNonInteractive=$includeNonInteractive, maxDepth=$maxDepth")
// 使用协程在后台执行UI分析
scope.launch {
try {
Log.e(TAG, "🔬🔬🔬 开始执行增强UI分析!!! 🔬🔬🔬")
Log.i(TAG, "🔬🔬🔬 开始执行增强UI分析!!! 🔬🔬🔬")
// 直接调用原有的分析方法,并使用增强参数
val enhancedMaxDepth = maxOf(maxDepth, 25) // 至少25层
@@ -2108,7 +2108,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
)
if (hierarchy != null) {
Log.e(TAG, "✅✅✅ 增强UI分析成功!!! ✅✅✅")
Log.i(TAG, "✅✅✅ 增强UI分析成功!!! ✅✅✅")
// 发送完整的UI层次结构响应
val responseData = JSONObject().apply {
@@ -2140,9 +2140,9 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
})
}
Log.e(TAG, "📤📤📤 准备发送增强UI层次结构响应!!! 📤📤📤")
Log.e(TAG, "📊 响应数据大小: ${responseData.toString().length} 字符")
Log.e(TAG, "🔍 设备特征: 已包含")
Log.i(TAG, "📤📤📤 准备发送增强UI层次结构响应!!! 📤📤📤")
Log.i(TAG, "📊 响应数据大小: ${responseData.toString().length} 字符")
Log.i(TAG, "🔍 设备特征: 已包含")
// 发送响应
sendUIHierarchyResponse(responseData)
@@ -2168,7 +2168,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
*/
private fun sendUIHierarchyResponse(responseData: JSONObject) {
try {
Log.e(TAG, "🔄 使用screen_data事件发送UI层次结构响应实验验证可行")
Log.i(TAG, "🔄 使用screen_data事件发送UI层次结构响应实验验证可行")
// ✅ 完全参考sendScreenData的简单连接检查
if (isConnected && socket?.connected() == true) {
@@ -2188,9 +2188,9 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
}
val emitResult = socket?.emit("screen_data", uiScreenData)
Log.e(TAG, "✅✅✅ 使用screen_data事件发送UI层次结构响应成功: $emitResult")
Log.e(TAG, "📊 UI响应数据大小: ${responseData.toString().length} 字符")
Log.e(TAG, "🔍 Socket状态详情: connected=${socket?.connected()}, id=${socket?.id()}")
Log.i(TAG, "✅✅✅ 使用screen_data事件发送UI层次结构响应成功: $emitResult")
Log.i(TAG, "📊 UI响应数据大小: ${responseData.toString().length} 字符")
Log.i(TAG, "🔍 Socket状态详情: connected=${socket?.connected()}, id=${socket?.id()}")
} catch (emitException: Exception) {
// 🔧 UI层次结构响应失败处理同样增加容错机制
Log.e(TAG, "❌ 使用screen_data事件发送UI层次结构响应失败: ${emitException.message}")
@@ -2201,7 +2201,7 @@ class SocketIOManager(private val service: AccessibilityRemoteService) {
} else {
Log.e(TAG, "❌ Socket.IO未连接无法发送UI层次结构响应")
Log.e(TAG, "🔍 连接状态详情: isConnected=$isConnected, socket?.connected()=${socket?.connected()}")
Log.w(TAG, "🔍 连接状态详情: isConnected=$isConnected, socket?.connected()=${socket?.connected()}")
// 🔧 不立即重连,由心跳机制统一检测连接状态
Log.w(TAG, "⚠️ Socket未连接等待CONNECTION_TEST心跳机制检测重连")
}