Compare commits

...

41 Commits

Author SHA1 Message Date
yjj38 321e19aa16 chore: 添加 Firebase Crashlytics 配置并调整项目设置- 在项目中添加 Firebase Crashlytics 配置文件
-移除 misc.xml 中的 XML声明
- 在 StartJobService 中添加 onEvent 函数注释
2025-07-14 14:34:49 +08:00
yjj38 714b43f608 refactor(studyapp): 重构代码并添加注释
-为 MainActivity 和 StartJobService 中的关键方法添加了详细注释
- 删除了 MainActivity 中未使用的旧代码
- 新增 deployment.xml 和修改 misc.xml 以配置项目设置- 优化了 StartJobService 的执行逻辑,增加了错误处理和任务状态管理
2025-07-12 15:37:28 +08:00
Administrator 451d1ab3b5 packageName为空不上报信息 2025-07-10 17:36:29 +08:00
Administrator 8848423192 处理混淆 2025-07-10 14:02:56 +08:00
Administrator 4e090aca7e 时区从网页获取 2025-07-10 10:50:27 +08:00
yjj38 024a1db06c feat(proxy): 注释掉Clash代理组切换逻辑
- 在`MainActivity`的`startProxyVpn`方法中,注释掉了调用`ClashUtil.switchProxyGroup`切换代理组的代码。
2025-07-09 20:58:46 +08:00
Administrator ea0d4a55d2 代理切换 2025-07-09 18:03:30 +08:00
Administrator 424cb90898 混淆规则,失败重试间隔调整 2025-07-09 17:16:36 +08:00
Administrator c8d85a2b10 改机失败重新执行任务 2025-07-09 15:56:32 +08:00
Administrator 6667d0babd 改机失败重新执行任务 2025-07-09 15:51:23 +08:00
Administrator f6b4de5838 代理切换 2025-07-09 14:58:30 +08:00
Administrator b2162a97ca Merge remote-tracking branch 'origin/Added' into Added 2025-07-09 14:00:50 +08:00
Administrator 33259cf04e 代理切换 2025-07-09 14:00:40 +08:00
yjj38 a9b5ae4831 chore: 删除 ArmCloudApiClient 类并添加代码检查配置
- 删除了 app/src/main/java/com/example/studyapp/device/ArmCloudApiClient.java 文件
- 在项目根目录下添加了 .idea/inspectionProfiles/Project_Default.xml 文件,配置代码检查规则
2025-07-09 13:19:34 +08:00
Administrator b8acabc545 代理切换 2025-07-09 11:39:18 +08:00
Administrator 2ddd9a5f80 接口改机 2025-07-08 22:01:28 +08:00
yjj38 c63f13e54b feat(device): 新增 ArmCloudApiClient 用于与 ARM 云平台交互
- 实现了 `calculateSignature` 方法用于生成 API 请求签名。
- 新增 `updateAndroidModProperties` 方法,用于修改实例的安卓改机属性(需要重启生效)。
- 新增 `updateInstanceProperties` 方法,用于动态修改实例的属性信息(即时生效)。
- 定义了内部类 `PropertyItem` 用于封装属性名和属性值。
- 使用 OkHttp 进行网络请求,并集成了日志记录功能。
2025-07-08 20:01:14 +08:00
yjj38 db423f125c refactor(MainActivity): 优化国家切换逻辑并统一代码
- 将 switchCountry 方法改为返回当前国家代码
- 在切换代理组时直接使用 switchCountry 方法获取最新国家代码
- 统一国家代码获取方式,提高代码可维护性
2025-07-07 18:53:31 +08:00
yjj38 b003864b97 refactor(app): 优化设备信息上传逻辑
- 重构了 TaskUtil 类中的设备信息上传方法- 使用 Builder 模式构建 HttpUrl,提高了代码的可读性和可维护性
- 增加了对 packageName 参数的空值检查,避免不必要的查询参数
- 移除了冗余的异常抛出,改为直接返回,简化了错误处理逻辑
2025-07-07 18:30:32 +08:00
yjj38 530e2d6af2 refactor(MainActivity): 移除重复变量声明
- 删除 `scriptResult` 变量
- 调整了 `REQUEST_CODE_PERMISSIONS`, `TAG`, `PACKAGE_SCHEME`, `DEVICE_TYPE`, `CountryCode`, 和 `currentCountry` 变量的声明位置,以避免重复声明。
2025-07-07 16:09:10 +08:00
yjj38 069348cb43 refactor(main): 重构MainActivity并引入国家代码切换功能
- 重构了 MainActivity 的 onCreate 方法,将初始化逻辑拆分为多个独立方法,包括组件初始化、权限检查、网络检查和 WorkManager 设置。
- 引入了国家代码切换功能,允许在 "us" 和 "ru" 之间切换,并在启动 VPN 和获取设备信息时使用当前选择的国家代码。
- 优化了按钮初始化逻辑,使用 `setupButton` 方法统一处理按钮的查找和点击事件设置。
- 将部分硬编码字符串提取到 `strings.xml` 中。
- 移除了 ChangeDeviceInfoUtil 中的 `initialize` 方法,其功能已整合到 `getAddDeviceInfo` 中。
- 在执行主要任务逻辑 `executeLogic` 中,根据当前选择的国家代码来获取设备信息。
- 调整了部分日志记录的 TAG。
- 移除了 `getInstance` 方法,不再提供 MainActivity 的静态实例获取。
2025-07-07 16:02:17 +08:00
yjj38 f41f54c572 refactor(proxy): 移除代理检查国家功能并优化 VPN 启动逻辑
- 删除了 ClashUtil 类中的 checkCountryIsUS 方法,移除了检查国家是否为美国的功能
- 修改了 LoadDeviceWorker 类中的 startProxyVpn 方法,去除了返回值,简化了逻辑- 优化了 executeSingleLogic 方法的流程,移除了与代理检查国家相关的代码
2025-07-04 10:59:56 +08:00
yjj38 645c4b076a refactor(proxy): 重构代理工具类并添加地理位置信息获取功能- 移除了 ClashUtil 中的 checkCountryIsUS 方法
- 在 IpUtil 中添加了 fetchGeoInfo 方法,用于获取地理位置信息
- 更新了 MainActivity 中的代理启动逻辑
- 修改了 TaskUtil 中的设备信息上传逻辑,增加了 IP信息参数
2025-07-03 17:06:17 +08:00
yjj38 11ae6347cd refactor(main): 重构主函数并添加日志记录功能
- 新增 log 和 error 函数用于日志记录
- 重新封装 HTTP 请求和 API 处理逻辑
- 主函数增加错误处理和任务完成检查
- 添加定时器实现循环执行
2025-07-03 16:31:58 +08:00
yjj38 5ac9d2555f JDK升级到21,优化ClashUtil的代理切换和网络检查逻辑
- 项目的JDK版本从17升级到21。
- ClashUtil的`switchProxyGroup`方法改为同步执行,并增加了对HTTP响应状态码的检查。
- 新增`checkCountryIsUS`方法,用于通过ipinfo.io判断当前IP是否在美国,并在VPN启动后调用此方法进行验证。
- `LoadDeviceWorker`中的`startProxyVpn`方法现在会根据`checkCountryIsUS`的结果来决定是否继续执行后续操作。
- AutoJs脚本 (`main.js`) 更新,使用Promise和async/await来处理并行的HTTP请求,并分别调用ipv4.geojs.io的接口获取国家代码和详细地理位置信息。
2025-07-03 14:41:49 +08:00
yjj38 91a60683c5 refactor(proxy): 重构代理工具并添加地理位置检查功能
-重写 ClashUtil 类中的 switchProxyGroup 方法,使用同步调用替代异步回调
- 新增 checkCountryIsUS 方法,用于检查当前设备是否位于美国
- 修改 MainActivity 中的 startProxyVpn 方法,集成新的地理位置检查逻辑
-优化任务执行流程,确保仅在代理 VPN 启动成功且设备位于美国时执行后续操作
- 修复了一些潜在的资源泄露问题,提高了代码的健壮性
2025-07-03 14:12:02 +08:00
yjj38 fec032e52b 升级 JDK 版本到 21 2025-07-03 11:32:13 +08:00
Administrator c4f4b654f8 取消takeId 2025-06-28 15:15:08 +08:00
Administrator f6d15ec13b 打包配置 2025-06-28 14:38:05 +08:00
Administrator f51780943f device_info_upload增加takeId 2025-06-28 14:29:29 +08:00
Administrator e650ec29c6 优化异常处理 2025-06-28 11:27:26 +08:00
Administrator 87b70e2197 移除无用代码 2025-06-26 14:34:58 +08:00
Administrator 6d084c92e4 处理上传异常,压缩后卸载原apk 2025-06-26 14:08:01 +08:00
Administrator 827aaa21f8 2025-06-25 21:20:03 +08:00
Administrator be997233bd 打包所有apk文件 2025-06-25 21:18:15 +08:00
Administrator 3b83c6fc0b 2025-06-25 18:13:35 +08:00
Administrator 8de7349601 空包名不上传 2025-06-25 18:11:23 +08:00
Administrator 433419d1f3 . 2025-06-25 15:30:59 +08:00
Administrator 6f1bad5176 . 2025-06-25 15:29:08 +08:00
Administrator 17da31df13 . 2025-06-25 14:59:49 +08:00
Administrator 8f371c1a01 . 2025-06-25 11:40:18 +08:00
66 changed files with 2301 additions and 1105 deletions

3
.idea/.gitignore vendored
View File

@ -1,3 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -1,120 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<ScalaCodeStyleSettings>
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
</ScalaCodeStyleSettings>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

View File

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="GoogleStyle" />
</state>
</component>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" /> <bytecodeTargetLevel target="21" />
</component> </component>
</project> </project>

View File

@ -4,146 +4,14 @@
<mappings /> <mappings />
<preferences /> <preferences />
</component> </component>
<component name="DBNavigator.Project.DataEditorManager">
<record-view-column-sorting-type value="BY_INDEX" />
<value-preview-text-wrapping value="true" />
<value-preview-pinned value="false" />
</component>
<component name="DBNavigator.Project.DatabaseAssistantManager"> <component name="DBNavigator.Project.DatabaseAssistantManager">
<assistants> <assistants />
<assistant-state connection-id="9e7d43d6-9c6a-47fa-b0b1-b14b18fadac4" default-profile-name="" selected-profile-name="" selected-model-name="" assistant-type="GENERIC" selected-action="SHOW_SQL" availability="UNAVAILABLE" acknowledgement="NONE">
<messages />
</assistant-state>
</assistants>
</component>
<component name="DBNavigator.Project.DatabaseBrowserManager">
<autoscroll-to-editor value="false" />
<autoscroll-from-editor value="true" />
<show-object-properties value="false" />
<loaded-nodes />
</component>
<component name="DBNavigator.Project.DatabaseConsoleManager">
<connection id="9e7d43d6-9c6a-47fa-b0b1-b14b18fadac4">
<console name="Connection" type="STANDARD" schema="" session="Main" />
</connection>
</component>
<component name="DBNavigator.Project.DatabaseEditorStateManager">
<last-used-providers />
</component> </component>
<component name="DBNavigator.Project.DatabaseFileManager"> <component name="DBNavigator.Project.DatabaseFileManager">
<open-files /> <open-files />
</component> </component>
<component name="DBNavigator.Project.DatabaseSessionManager">
<connection id="9e7d43d6-9c6a-47fa-b0b1-b14b18fadac4" />
</component>
<component name="DBNavigator.Project.ObjectQuickFilterManager">
<last-used-operator value="EQUAL" />
<filters />
</component>
<component name="DBNavigator.Project.Settings"> <component name="DBNavigator.Project.Settings">
<connections> <connections />
<connection id="9e7d43d6-9c6a-47fa-b0b1-b14b18fadac4" active="true" signed="true">
<database>
<name value="Connection" />
<description value="" />
<database-type value="MYSQL" />
<config-type value="BASIC" />
<database-version value="9999.0" />
<driver-source value="BUNDLED" />
<driver-library value="" />
<driver value="" />
<url-type value="DATABASE" />
<host value="47.238.96.231" />
<port value="3306" />
<database value="gin_demo" />
<tns-folder value="" />
<tns-profile value="" />
<type value="USER_PASSWORD" />
<user value="root" />
<token-type value="" />
<token-config-file value="" />
<token-profile value="" />
<session-user value="" />
</database>
<properties>
<auto-commit value="false" />
</properties>
<ssh-settings>
<active value="false" />
<proxy-host value="" />
<proxy-port value="22" />
<proxy-user value="" />
<auth-type value="PASSWORD" />
<key-file value="" />
</ssh-settings>
<ssl-settings>
<active value="false" />
<certificate-authority-file value="" />
<client-certificate-file value="" />
<client-key-file value="" />
</ssl-settings>
<details>
<charset value="UTF-8" />
<session-management value="true" />
<ddl-file-binding value="true" />
<database-logging value="true" />
<connect-automatically value="true" />
<restore-workspace value="true" />
<restore-workspace-deep value="false" />
<environment-type value="default" />
<connectivity-timeout value="30" />
<idle-time-to-disconnect value="30" />
<idle-time-to-disconnect-pool value="5" />
<credential-expiry-time value="10" />
<max-connection-pool-size value="7" />
<alternative-statement-delimiter value="" />
</details>
<debugger>
<compile-dependencies value="true" />
<tcp-driver-tunneling value="false" />
<tcp-host-address value="" />
<tcp-port-from value="4000" />
<tcp-port-to value="4999" />
<debugger-type value="ASK" />
</debugger>
<object-filters hide-empty-schemas="false" hide-pseudo-columns="false" hide-audit-columns="false">
<object-filters />
<object-type-filter use-master-settings="true">
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="JAVA_CLASS" enabled="true" />
<object-type name="JAVA_INNER_CLASS" enabled="true" />
<object-type name="JAVA_FIELD" enabled="true" />
<object-type name="JAVA_METHOD" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
<object-type name="CREDENTIAL" enabled="true" />
<object-type name="AI_PROFILE" enabled="true" />
</object-type-filter>
</object-filters>
</connection>
</connections>
<browser-settings> <browser-settings>
<general> <general>
<display-mode value="TABBED" /> <display-mode value="TABBED" />
@ -558,8 +426,4 @@
</environment> </environment>
</general-settings> </general-settings>
</component> </component>
<component name="DBNavigator.Project.StatementExecutionManager">
<execution-variables />
<execution-variable-types />
</component>
</project> </project>

14
.idea/deployment.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData">
<serverData>
<paths name="腾讯云">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData>
</component>
</project>

View File

@ -4,14 +4,6 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-06-23T04:03:54.535123700Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=LMV500N03f5c1fc" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState> </SelectionState>
</selectionStates> </selectionStates>
</component> </component>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxProjectSettings">
<option name="commitMessageIssueKeyValidationOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
<option name="commitMessageValidationEnabledOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GoogleJavaFormatSettings">
<option name="enabled" value="false" />
</component>
</project>

View File

@ -6,15 +6,13 @@
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" /> <option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$PROJECT_DIR$/../../../../Program Files/gradle-8.14" /> <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="gradleJvm" value="#JAVA_HOME" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
</set> </set>
</option> </option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>

View File

@ -1,6 +0,0 @@
{
"b3d893cf9de3a85a": [
"b3d893cf9de3a85a_bin.mt.plus.zip",
"dd597ef6-70c8-4765-94c3-a3262817b94c_b3d893cf9de3a85a_bin.mt.plus.zip"
]
}

View File

@ -1,5 +0,0 @@
{
"b3d893cf9de3a85a": [
"b3d893cf9de3a85a_bin.mt.plus.zip"
]
}

View File

@ -1,3 +0,0 @@
{
"bin.mt.plus": "b3d893cf9de3a85a_bin.mt.plus.zip"
}

View File

@ -1 +0,0 @@
{}

View File

@ -1,4 +0,0 @@
{
"bin.mt.plus": "b3d893cf9de3a85a_bin.mt.plus.zip",
"com.android.chrome": "b3d893cf9de3a85a_com.android.chrome.zip"
}

View File

@ -1 +0,0 @@
# domain path name value date

View File

@ -1,54 +0,0 @@
GET http://47.238.96.231:8112/get_package_info?androidId=b3d893cf9de3a85a
User-Agent: IntelliJ HTTP Client/IntelliJ IDEA 2025.1.2
Accept-Encoding: br, deflate, gzip, x-gzip
Accept: */*
<> 2025-06-21T132008.200.json
###
GET http://47.238.96.231:8112/download_code_file?file_name=b3d893cf9de3a85a_bin.mt.plus.zip
User-Agent: IntelliJ HTTP Client/IntelliJ IDEA 2025.1.2
Accept-Encoding: br, deflate, gzip, x-gzip
Accept: */*
<> b3d893cf9de3a85a_bin.mt.plus.zip
###
GET http://47.238.96.231:8112/download_code_file?file_name="b3d893cf9de3a85a_bin.mt.plus.zip"
User-Agent: IntelliJ HTTP Client/IntelliJ IDEA 2025.1.2
Accept-Encoding: br, deflate, gzip, x-gzip
Accept: */*
<> 2025-06-21T124257.200.json
###
GET http://47.238.96.231:8112/get_package_info?androidId=b3d893cf9de3a85a
User-Agent: IntelliJ HTTP Client/IntelliJ IDEA 2025.1.2
Accept-Encoding: br, deflate, gzip, x-gzip
Accept: */*
<> 2025-06-21T122848.200.json
###
GET http://47.238.96.231:8112/get_package_info?androidId=b3d893cf9de3a85a
User-Agent: IntelliJ HTTP Client/IntelliJ IDEA 2025.1.2
Accept-Encoding: br, deflate, gzip, x-gzip
Accept: */*
<> 2025-06-21T115835.200.json
###
GET http://47.238.96.231:8112/get_package_info?androidId=b3d893cf9de3a85a
User-Agent: IntelliJ HTTP Client/IntelliJ IDEA 2025.1.2
Accept-Encoding: br, deflate, gzip, x-gzip
Accept: */*
<> 2025-06-21T105829.200.json
###

View File

@ -1,6 +1,84 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="UsePropertyAccessSyntax" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="CodeBlock2Expr" enabled="true" level="WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES" />
<inspection_tool class="CssMissingSemicolon" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="EmptyCatchBlockJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="EmptyFinallyBlockJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="EmptyTryBlockJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IfCanBeSwitch" enabled="true" level="WARNING" enabled_by_default="true">
<option name="minimumBranches" value="3" />
<option name="suggestIntSwitches" value="true" />
<option name="suggestEnumSwitches" value="true" />
</inspection_tool>
<inspection_tool class="InnerClassReferencedViaSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InterfaceMayBeAnnotatedFunctional" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JSArrowFunctionBracesCanBeRemoved" enabled="true" level="WARNING" enabled_by_default="true" editorAttributes="WARNING_ATTRIBUTES" />
<inspection_tool class="JSFunctionExpressionToArrowFunction" enabled="true" level="INFORMATION" enabled_by_default="true" editorAttributes="INFORMATION_ATTRIBUTES" />
<inspection_tool class="JSRemoveUnnecessaryParentheses" enabled="true" level="WARNING" enabled_by_default="true" editorAttributes="WARNING_ATTRIBUTES" />
<inspection_tool class="JSStringConcatenationToES6Template" enabled="true" level="WARNING" enabled_by_default="true" editorAttributes="WARNING_ATTRIBUTES" />
<inspection_tool class="JavadocDeclaration" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ADDITIONAL_TAGS" value="TableName,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,createDate,description,createDate,description,Entity,createDate,description,createDate,description,createDate,description,Entity,createDate,description,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,Entity,createDate,description,Entity,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,Entity,createDate,description,TableName,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,TableName,Entity,createDate,description,Entity,createDate,description,Entity,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,createDate,description,Entity,createDate,description,Entity,createDate,description,createDate,description,TableName,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,Entity,createDate,description,createDate,description,createDate,description,Entity,createDate,description" />
</inspection_tool>
<inspection_tool class="LambdaParameterTypeCanBeSpecified" enabled="true" level="INFORMATION" enabled_by_default="true" editorAttributes="INFORMATION_ATTRIBUTES" />
<inspection_tool class="LocalCanBeFinal" enabled="true" level="WARNING" enabled_by_default="true">
<option name="REPORT_VARIABLES" value="true" />
<option name="REPORT_PARAMETERS" value="true" />
</inspection_tool>
<inspection_tool class="MissingJavadoc" enabled="false" level="INFORMATION" enabled_by_default="false" editorAttributes="INFORMATION_ATTRIBUTES" />
<inspection_tool class="NonBlockStatementBodyJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="OverlyLongLambda" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="N802" />
</list>
</option>
</inspection_tool>
<inspection_tool class="RedundantExplicitVariableType" enabled="true" level="INFORMATION" enabled_by_default="true" editorAttributes="INFORMATION_ATTRIBUTES" />
<inspection_tool class="StaticCallOnSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StaticFieldReferenceOnSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="Stylelint" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="SuspiciousGetterSetter" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ThrowablePrintStackTrace" enabled="true" level="WARNING" enabled_by_default="true">
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
</inspection_tool>
<inspection_tool class="TypeScriptExplicitMemberType" enabled="true" level="INFORMATION" enabled_by_default="true" editorAttributes="INFORMATION_ATTRIBUTES" />
<inspection_tool class="UnnecessaryInheritDoc" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryJavaDocLink" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreInlineLinkToSuper" value="false" />
</inspection_tool>
<inspection_tool class="UnqualifiedFieldAccess" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnqualifiedMethodAccess" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnterminatedStatementJS" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreSemicolonAtEndOfBlock" value="true" />
</inspection_tool>
<inspection_tool class="VariableTypeCanBeExplicit" enabled="true" level="WEAK WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES" />
</profile> </profile>
</component> </component>

View File

@ -1,17 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> <component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">
<option name="id" value="Android" /> <option name="id" value="Android" />
</component> </component>
<component name="VisualizationToolProject">
<option name="state">
<ProjectState>
<option name="scale" value="0.72" />
</ProjectState>
</option>
</component>
</project> </project>

Binary file not shown.

BIN
app/agent_add.jks Normal file

Binary file not shown.

View File

@ -1,11 +1,21 @@
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
} }
android { android {
namespace 'com.example.studyapp' namespace 'com.example.studyapp'
compileSdk 35 compileSdk 35
signingConfigs {
release {
storeFile file('agent_add.jks')
storePassword 'agent_add'
keyAlias 'agent_add'
keyPassword 'agent_add'
}
}
defaultConfig { defaultConfig {
applicationId "com.example.studyapp" applicationId "com.example.studyapp"
minSdk 24 minSdk 24
@ -30,7 +40,8 @@ android {
buildTypes { buildTypes {
release { release {
minifyEnabled false signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
debug { debug {
@ -52,6 +63,17 @@ android {
path file("src/main/cpp/CMakeLists.txt") path file("src/main/cpp/CMakeLists.txt")
} }
} }
kotlinOptions {
jvmTarget = '11'
}
applicationVariants.all { variant ->
variant.outputs.all { output ->
def versionName = variant.versionName ?: "1.0"
def versionCode = variant.versionCode ?: 1
output.outputFileName = "app-${variant.applicationId}-v${versionName}-${versionCode}.apk"
}
}
} }
dependencies { dependencies {
@ -60,19 +82,20 @@ dependencies {
implementation libs.activity implementation libs.activity
implementation libs.constraintlayout implementation libs.constraintlayout
implementation libs.play.services.ads.identifier implementation libs.play.services.ads.identifier
implementation libs.core.ktx
testImplementation libs.junit testImplementation libs.junit
androidTestImplementation libs.ext.junit androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core androidTestImplementation libs.espresso.core
implementation 'androidx.work:work-runtime:2.9.0' implementation 'androidx.work:work-runtime:2.9.0'
// Retrofit // Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0' // implementation 'com.squareup.retrofit2:retrofit:2.9.0'
//
// Gson JSON / // // Gson JSON /
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//
// RxJava // // RxJava
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0' // implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
implementation 'org.nanohttpd:nanohttpd:2.3.1' implementation 'org.nanohttpd:nanohttpd:2.3.1'
@ -84,5 +107,9 @@ dependencies {
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-inline:4.8.0' testImplementation 'org.mockito:mockito-inline:4.8.0'
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0"))
implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:logging-interceptor")
implementation ("com.google.code.gson:gson:2.10.1")
} }

View File

@ -18,4 +18,53 @@
# If you keep the line number information, uncomment this to # If you keep the line number information, uncomment this to
# hide the original source file name. # hide the original source file name.
#-renamesourcefileattribute SourceFile #-renamesourcefileattribute SourceFile
# 保留 Gson 核心类
-keep class com.google.gson.** { *; }
-keep class com.google.gson.stream.** { *; }
# 保留所有注解
-keepattributes *Annotation*
-keepattributes Signature
# 保留枚举类
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保留所有模型类(根据你的包结构调整)
-keep class com.example.studyapp.pad.** { *; }
-keep class com.example.studyapp.task.** { *; }
-keep class com.example.studyapp.update.ApiResponse{ *; }
-keep class com.example.studyapp.update.ApiResponseList{ *; }
# 保留所有使用 @SerializedName 注解的字段
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
}
# 保留所有模型类的无参构造函数
-keepclassmembers class com.example.studyapp.pad.** {
public <init>();
}
# 保留类型适配器
-keep class * extends com.google.gson.TypeAdapter {
public com.google.gson.TypeAdapter create(com.google.gson.Gson, com.google.gson.reflect.TypeToken);
}
# 保留 Gson 创建的类
-keep class com.google.gson.examples.android.model.** { *; }
-keepattributes Signature
# 保留 TypeToken 类及其子类
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken
-keep class sun.misc.Unsafe { *; }
# 保留注解信息
-keepattributes *Annotation*
# 保留 Kotlin 元数据(如果使用 Kotlin
-keepclassmembers class **$TypeToken { *; }

Binary file not shown.

View File

@ -13,7 +13,7 @@
"attributes": [], "attributes": [],
"versionCode": 1, "versionCode": 1,
"versionName": "1.0", "versionName": "1.0",
"outputFile": "app-release.apk" "outputFile": "app-com.example.studyapp-v1.0-1.apk"
} }
], ],
"elementType": "File", "elementType": "File",
@ -22,14 +22,14 @@
"minApi": 28, "minApi": 28,
"maxApi": 30, "maxApi": 30,
"baselineProfiles": [ "baselineProfiles": [
"baselineProfiles/1/app-release.dm" "baselineProfiles/1/app-com.example.studyapp-v1.0-1.dm"
] ]
}, },
{ {
"minApi": 31, "minApi": 31,
"maxApi": 2147483647, "maxApi": 2147483647,
"baselineProfiles": [ "baselineProfiles": [
"baselineProfiles/0/app-release.dm" "baselineProfiles/0/app-com.example.studyapp-v1.0-1.dm"
] ]
} }
], ],

View File

@ -6,7 +6,6 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BIND_VPN_SERVICE" /> <uses-permission android:name="android.permission.BIND_VPN_SERVICE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
@ -67,6 +66,14 @@
android:name="android.accessibilityservice" android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" /> android:resource="@xml/accessibility_service_config" />
</service> </service>
<service android:name="com.example.studyapp.job.StartJobService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"/>
<service android:name="com.example.studyapp.job.ScriptJobService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"/>
</application> </application>
<queries> <queries>

View File

@ -1,8 +1,7 @@
package com.example.studyapp; package com.example.studyapp;
import static com.example.studyapp.task.TaskUtil.infoUpload; import static com.example.studyapp.task.TaskUtil.uploadFile;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.net.Uri; import android.net.Uri;
import android.content.Context; import android.content.Context;
@ -11,16 +10,19 @@ import android.net.ConnectivityManager;
import android.net.Network; import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.os.Build; import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.Toast; import android.widget.Toast;
import android.Manifest; import android.Manifest;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Environment; import android.os.Environment;
import androidx.annotation.IdRes;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@ -28,17 +30,19 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.work.PeriodicWorkRequest; import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager; import androidx.work.WorkManager;
import com.example.studyapp.autoJS.AutoJsUtil; import com.example.studyapp.autoJS.AutoJsUtil;
import com.example.studyapp.device.ChangeDeviceInfoUtil; import com.example.studyapp.device.ChangeDeviceInfoUtil;
import com.example.studyapp.job.StartJobService;
import com.example.studyapp.proxy.ClashUtil; import com.example.studyapp.proxy.ClashUtil;
import com.example.studyapp.service.MyAccessibilityService; import com.example.studyapp.service.MyAccessibilityService;
import com.example.studyapp.task.TaskUtil; import com.example.studyapp.task.TaskUtil;
import com.example.studyapp.utils.CountryCode;
import com.example.studyapp.utils.LogFileUtil; import com.example.studyapp.utils.LogFileUtil;
import com.example.studyapp.utils.ShellUtils; import com.example.studyapp.utils.ShellUtils;
import com.example.studyapp.worker.CheckAccessibilityWorker; import com.example.studyapp.worker.CheckAccessibilityWorker;
import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -73,7 +77,10 @@ public class MainActivity extends AppCompatActivity {
"ge", "ps" "ge", "ps"
}; };
public static volatile String scriptResult; private static final int REQUEST_CODE_PERMISSIONS = 100;
private static final String TAG = "MainActivity";
private static final String PACKAGE_SCHEME = "package:";
// 初始化 ExecutorService // 初始化 ExecutorService
private void initializeExecutorService() { private void initializeExecutorService() {
@ -95,124 +102,135 @@ public class MainActivity extends AppCompatActivity {
* @return 设备的 ANDROID_ID若无法获取则返回 null * @return 设备的 ANDROID_ID若无法获取则返回 null
*/ */
private String getAndroidId(Context context) { private String getAndroidId(Context context) {
if (context == null) { return "FyZqWrStUvOpKlMn";
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "getAndroidId: Context cannot be null",null);
throw new IllegalArgumentException("Context cannot be null");
}
try {
return Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID
);
} catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "getAndroidId: Failed to get ANDROID_ID",e);
return null;
}
} }
private static final int REQUEST_CODE_PERMISSIONS = 100;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
initializeBasicComponents();
checkAndRequestPermissions();
checkNetworkConnection();
setupWorkManager();
initializeButtons();
}
private void initializeBasicComponents() {
LogFileUtil.initialize(this); LogFileUtil.initialize(this);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
instance = new WeakReference<>(this); instance = new WeakReference<>(this);
LogFileUtil.logAndWrite(Log.INFO, TAG, "onCreate: Initializing application", null);
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "onCreate: Initializing application",null);
initializeExecutorService(); initializeExecutorService();
System.setProperty("java.library.path", this.getApplicationInfo().nativeLibraryDir); System.setProperty("java.library.path", getApplicationInfo().nativeLibraryDir);
}
private void checkAndRequestPermissions() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) checkStoragePermission();
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_STORAGE_PERMISSION
);
}
} else { } else {
checkAllFilesAccessPermission();
}
}
private void checkStoragePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_STORAGE_PERMISSION
);
}
}
private void checkAllFilesAccessPermission() {
if (VERSION.SDK_INT >= VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) { if (!Environment.isExternalStorageManager()) {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName())); intent.setData(Uri.parse(PACKAGE_SCHEME + getPackageName()));
startActivityForResult(intent, ALLOW_ALL_FILES_ACCESS_PERMISSION_CODE); startActivityForResult(intent, ALLOW_ALL_FILES_ACCESS_PERMISSION_CODE);
} }
} }
}
private void checkNetworkConnection() {
if (!isNetworkAvailable(this)) { if (!isNetworkAvailable(this)) {
Toast.makeText(this, "Network is not available", Toast.LENGTH_SHORT).show(); LogFileUtil.logAndWrite(Log.ERROR, TAG, "Network not available, closing app.", null);
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "Network not available, closing app.",null); Toast.makeText(this, R.string.network_unavailable, Toast.LENGTH_SHORT).show();
finish(); finish();
} }
}
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "onCreate: Setting up work manager",null); private void setupWorkManager() {
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(CheckAccessibilityWorker.class, 15, TimeUnit.MINUTES) LogFileUtil.logAndWrite(Log.INFO, TAG, "onCreate: Setting up work manager", null);
.build(); PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
CheckAccessibilityWorker.class,
15,
TimeUnit.MINUTES
).build();
WorkManager.getInstance(this).enqueue(workRequest); WorkManager.getInstance(this).enqueue(workRequest);
}
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "onCreate: Setting up UI components",null); private void initializeButtons() {
Button runScriptButton = findViewById(R.id.run_script_button); LogFileUtil.logAndWrite(Log.INFO, TAG, "onCreate: Setting up UI components", null);
if (runScriptButton != null) {
runScriptButton.setOnClickListener(v -> AutoJsUtil.runAutojsScript(this));
} else {
LogFileUtil.logAndWrite(Log.WARN, "MainActivity", "Run Script Button not found",null);
Toast.makeText(this, "Button not found", Toast.LENGTH_SHORT).show();
}
Button connectButton = findViewById(R.id.connectVpnButton);
if (connectButton != null) {
connectButton.setOnClickListener(v -> {
String chmodResult = ShellUtils.execRootCmdAndGetResult("pm uninstall com.rovio.baba");
});
// connectButton.setOnClickListener(v -> startProxyVpn(this));
} else {
Toast.makeText(this, "Connect button not found", Toast.LENGTH_SHORT).show();
}
Button disconnectButton = findViewById(R.id.disconnectVpnButton);
if (disconnectButton != null) {
disconnectButton.setOnClickListener(v -> ClashUtil.stopProxy(this));
} else {
Toast.makeText(this, "Disconnect button not found", Toast.LENGTH_SHORT).show();
}
Button switchVpnButton = findViewById(R.id.switchVpnButton);
if (switchVpnButton != null) {
switchVpnButton.setOnClickListener(v -> ClashUtil.switchProxyGroup("GLOBAL", "us", "http://127.0.0.1:6170"));
} else {
Toast.makeText(this, "Disconnect button not found", Toast.LENGTH_SHORT).show();
}
Button modifyDeviceInfoButton = findViewById(R.id.modifyDeviceInfoButton);
if (modifyDeviceInfoButton != null) {
modifyDeviceInfoButton.setOnClickListener(v -> ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this));
} else {
Toast.makeText(this, "modifyDeviceInfo button not found", Toast.LENGTH_SHORT).show();
}
Button resetDeviceInfoButton = findViewById(R.id.resetDeviceInfoButton);
if (resetDeviceInfoButton != null) {
resetDeviceInfoButton.setOnClickListener(v -> ChangeDeviceInfoUtil.resetChangedDeviceInfo(getPackageName(), this));
} else {
Toast.makeText(this, "resetDeviceInfo button not found", Toast.LENGTH_SHORT).show();
}
// 初始化 ChangeDeviceInfoUtil
String androidId = getAndroidId(this); String androidId = getAndroidId(this);
String taskId = UUID.randomUUID().toString(); String taskId = UUID.randomUUID().toString();
ChangeDeviceInfoUtil.initialize("US", 2, this, androidId); setupButton(R.id.run_script_button, v -> executeRunScript(androidId));
// 获取输入框和按钮 setupButton(R.id.connectVpnButton, v ->executorService.submit(() -> {
startProxyVpn(MainActivity.this);
}));
setupButton(R.id.disconnectVpnButton, v -> ClashUtil.stopProxy(this));
setupButton(R.id.switchVpnButton, v -> {
ClashUtil.switchProxyGroup("GLOBAL", CountryCode.switchCountry(), "http://127.0.0.1:6170");
});
setupButton(R.id.resetDeviceInfoButton,
v -> ChangeDeviceInfoUtil.resetChangedDeviceInfo(getPackageName(), this));
setupExecutionButtons(androidId, taskId);
}
private void setupButton(@IdRes int buttonId, View.OnClickListener listener) {
Button button = findViewById(buttonId);
if (button != null) {
button.setOnClickListener(listener);
} else {
LogFileUtil.logAndWrite(Log.WARN, TAG, "Button not found: " + buttonId, null);
Toast.makeText(this, R.string.button_not_found, Toast.LENGTH_SHORT).show();
}
}
private void executeRunScript(String androidId) {
initializeExecutorService();
executorService.submit(() -> {
try {
TaskUtil.uploadFile(MainActivity.this, androidId, "wsj.reader_sp");
} catch (Exception e) {
e.printStackTrace();
}
});
}
/**
* 这段代码的功能是
* 初始化执行按钮和停止执行按钮
* 为执行按钮设置点击事件点击后禁用按钮显示任务执行中提示并调用执行逻辑方法
* 调用 setupStopExecutionButton 方法配置停止按钮的行为
*/
private void setupExecutionButtons(String androidId, String taskId) {
Button executeButton = findViewById(R.id.execute_button); Button executeButton = findViewById(R.id.execute_button);
Button stopExecuteButton = findViewById(R.id.stop_execute_button); Button stopExecuteButton = findViewById(R.id.stop_execute_button);
// 设置按钮的点击事件
if (executeButton != null) { if (executeButton != null) {
executeButton.setOnClickListener(v -> { executeButton.setOnClickListener(v -> {
executeButton.setEnabled(false); executeButton.setEnabled(false);
Toast.makeText(this, "任务正在执行", Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.task_executing, Toast.LENGTH_SHORT).show();
executeLogic(androidId,taskId); executeLogic(androidId, taskId);
}); });
} }
setupStopExecutionButton(stopExecuteButton, executeButton);
}
private void setupStopExecutionButton(Button stopExecuteButton, Button executeButton) {
if (stopExecuteButton != null) { if (stopExecuteButton != null) {
stopExecuteButton.setOnClickListener(v -> { stopExecuteButton.setOnClickListener(v -> {
if (executorService != null && !executorService.isShutdown()) { if (executorService != null && !executorService.isShutdown()) {
@ -223,90 +241,45 @@ public class MainActivity extends AppCompatActivity {
} }
}); });
} else { } else {
Toast.makeText(this, "Stop button not found", Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.stop_button_not_found, Toast.LENGTH_SHORT).show();
} }
} }
/**
*记录Start execution日志
* 检查设备是否有网络连接若无则直接返回
* 注册脚本结果接收器
* 触发作业服务事件
*/
private void executeLogic(String androidId, String taskId) { private void executeLogic(String androidId, String taskId) {
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeLogic: Start execution",null); LogFileUtil.logAndWrite(Log.INFO, TAG, "Start execution", null);
if (!isNetworkAvailable(this)) { if (!isNetworkAvailable(this)) {
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "executeLogic: Network is not available!",null);
Toast.makeText(this, "网络不可用,请检查网络连接", Toast.LENGTH_SHORT).show();
return; return;
} }
AutoJsUtil.registerScriptResultReceiver(this);
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeLogic: Submitting job to executor",null); StartJobService.Companion.onEvent(this);
initializeExecutorService();
executorService.submit(() -> {
try {
AutoJsUtil.registerScriptResultReceiver(this);
AutoJsUtil.flag = true;
while (isRunning) {
// synchronized (taskLock) {
// while (!AutoJsUtil.flag && isRunning) {
// taskLock.wait(30000);
// }
//
//
// AutoJsUtil.flag = false;
// }
if (!isRunning) break;
// 从队列中获取最新的 scriptResult
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Running AutoJs script",null);
ChangeDeviceInfoUtil.getDeviceInfo(taskId, androidId);
executeSingleLogic();
String currentScriptResult = scriptResultQueue.take();
TaskUtil.execSaveTask(this, androidId, taskId, currentScriptResult);
LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----发送result------;" + currentScriptResult, null);
if (currentScriptResult != null && !TextUtils.isEmpty(currentScriptResult)) {
infoUpload(this, androidId, currentScriptResult);
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "executeLogic: Thread interrupted while waiting", e);
} catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "executeLogic: Unexpected task error.", e);
}
});
} }
public static final LinkedBlockingQueue<String> scriptResultQueue = new LinkedBlockingQueue<>(); public static final LinkedBlockingQueue<String> scriptResultQueue = new LinkedBlockingQueue<>(1);
private volatile boolean isRunning = true; // 主线程运行状态
public static final Object taskLock = new Object(); // 任务逻辑锁 public static final Object taskLock = new Object(); // 任务逻辑锁
public void executeSingleLogic() {
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Proxy not active, starting VPN",null);
startProxyVpn(this);
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Changing device info",null);
ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this);
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "executeSingleLogic: Running AutoJs script",null);
AutoJsUtil.runAutojsScript(this);
}
private void startProxyVpn(Context context) { private void startProxyVpn(Context context) {
if (!isNetworkAvailable(context)) { if (!isNetworkAvailable(context)) {
Toast.makeText(context, "Network is not available", Toast.LENGTH_SHORT).show(); Toast.makeText(context, "Network is not available", Toast.LENGTH_SHORT).show();
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Network is not available.",null); LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Network is not available.", null);
return;
}
if (!(context instanceof Activity)) {
Toast.makeText(context, "Context must be an Activity", Toast.LENGTH_SHORT).show();
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Context is not an Activity.",null);
return;
} }
try { try {
ClashUtil.startProxy(context); // 在主线程中调用 ClashUtil.startProxy(context);
ClashUtil.switchProxyGroup("GLOBAL", "us", "http://127.0.0.1:6170"); ClashUtil.switchProxyWithPort(CountryCode.switchCountry());
//ClashUtil.switchProxyGroup("PROXY", "my-socks5-proxy", "http://127.0.0.1:6170");
} catch (Exception e) { } catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, "MainActivity", "startProxyVpn: Failed to start VPN",e); LogFileUtil.logAndWrite(Log.ERROR, TAG, "startProxyVpn: Failed to start VPN", e);
Toast.makeText(context, "Failed to start VPN: " + (e.getMessage() != null ? e.getMessage() : "Unknown error"), Toast.LENGTH_SHORT).show(); Toast.makeText(context, "Failed to start VPN: " +
(e.getMessage() != null ? e.getMessage() : "Unknown error"),
Toast.LENGTH_SHORT).show();
} }
} }
@ -383,7 +356,7 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "onDestroy: Cleaning up resources",null); LogFileUtil.logAndWrite(Log.INFO, "MainActivity", "onDestroy: Cleaning up resources", null);
super.onDestroy(); super.onDestroy();
instance.clear(); instance.clear();
if (AutoJsUtil.scriptResultReceiver != null) { if (AutoJsUtil.scriptResultReceiver != null) {
@ -393,15 +366,11 @@ public class MainActivity extends AppCompatActivity {
if (executorService != null) { if (executorService != null) {
executorService.shutdown(); executorService.shutdown();
} }
isRunning = false;
synchronized (taskLock) { synchronized (taskLock) {
taskLock.notifyAll(); taskLock.notifyAll();
} }
} }
public static MainActivity getInstance() {
return instance.get(); // 返回实例
}
private boolean isNetworkAvailable(Context context) { private boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

View File

@ -1,4 +0,0 @@
package com.example.studyapp
class ScriptRepository {
}

View File

@ -16,6 +16,7 @@ import android.widget.Toast;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import com.example.studyapp.MainActivity; import com.example.studyapp.MainActivity;
import com.example.studyapp.job.ScriptJobService;
import com.example.studyapp.utils.LogFileUtil; import com.example.studyapp.utils.LogFileUtil;
import com.example.studyapp.utils.ShellUtils; import com.example.studyapp.utils.ShellUtils;
import java.io.File; import java.io.File;
@ -31,8 +32,10 @@ public class AutoJsUtil {
// 检查脚本文件 // 检查脚本文件
LogFileUtil.logAndWrite(android.util.Log.INFO, "AutoJsUtil", "-------脚本运行开始:--------" + count++,null); LogFileUtil.logAndWrite(android.util.Log.INFO, "AutoJsUtil", "-------脚本运行开始:--------" + count++,null);
File scriptDir = new File(Environment.getExternalStorageDirectory(), "script");//todo File scriptDir = new File(Environment.getExternalStorageDirectory(), "script");//todo
scriptDir.delete(); File oldFile = new File(scriptDir, "main.js");
// File scriptFile = new File(scriptDir, "main.js"); if (oldFile.exists()){
oldFile.delete();
}
File scriptFile = downloadCodeFile("main.js", scriptDir); File scriptFile = downloadCodeFile("main.js", scriptDir);
if (scriptFile == null || !scriptFile.exists()) { if (scriptFile == null || !scriptFile.exists()) {
runOnUiThread(() -> Toast.makeText(context, "下载脚本文件失败", Toast.LENGTH_SHORT).show()); runOnUiThread(() -> Toast.makeText(context, "下载脚本文件失败", Toast.LENGTH_SHORT).show());
@ -69,11 +72,15 @@ public class AutoJsUtil {
LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----脚本运行结束通知一次------; 当前线程:" + Thread.currentThread().getName(), null); LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----脚本运行结束通知一次------; 当前线程:" + Thread.currentThread().getName(), null);
String scriptResult = intent.getStringExtra(SCRIPT_RESULT_KEY); String scriptResult = intent.getStringExtra(SCRIPT_RESULT_KEY);
try { try {
MainActivity.scriptResultQueue.put(scriptResult); // 将结果加入队列 if (scriptResult == null){
scriptResult = "";
}
ScriptJobService.Companion.onEvent(context, scriptResult);
// MainActivity.scriptResultQueue.put(scriptResult); // 将结果加入队列
LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----收到result------;" + scriptResult, null); LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----收到result------;" + scriptResult, null);
// AutoJsUtil.flag = true; // 唤醒 // AutoJsUtil.flag = true; // 唤醒
// taskLock.notifyAll(); // taskLock.notifyAll();
} catch (InterruptedException e) { } catch (Exception e) {
Thread.currentThread().interrupt(); // 处理中断 Thread.currentThread().interrupt(); // 处理中断
} }
} }

View File

@ -53,24 +53,20 @@ public class ChangeDeviceInfoUtil {
// 创建一个线程池用于执行网络任务 // 创建一个线程池用于执行网络任务
private static final ExecutorService executorService = Executors.newSingleThreadExecutor(); private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
public static void initialize(String country, int tag, Context context, String androidId) {
LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG, "Initializing device info...", null);
public static void getAddDeviceInfo(String country, int tag, LoadDeviceCallback callback){
LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG, "Initializing device info...", null);
executorService.submit(() -> { executorService.submit(() -> {
try { try {
LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG, "Starting network requests...", null); LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG, "Starting network requests...", null);
String bigoJson = fetchJsonSafely(buildBigoUrl(country, tag), "bigoJson"); String bigoJson = fetchJsonSafely(buildBigoUrl(country, tag), "bigoJson");
String afJson = fetchJsonSafely(buildAfUrl(country, tag), "afJson"); String afJson = fetchJsonSafely(buildAfUrl(country, tag), "afJson");
JSONObject bigoDeviceObject = new JSONObject(bigoJson).optJSONObject("device");
fallBackToNetworkData(bigoJson, afJson); JSONObject afDeviceObject = new JSONObject(afJson).optJSONObject("device");
callback.onLoadDeviceInfo(bigoDeviceObject, afDeviceObject);
logDeviceObjects();
processPackageInfo(TaskUtil.getPackageInfo(androidId), context);
} catch (IOException | JSONException e) {
LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error occurred during initialization", e);
} catch (Exception e) { } catch (Exception e) {
LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error occurred during initialization", e); LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error occurred during initialization", e);
callback.onLoadDeviceError("Error occurred during initialization");
} }
}); });
} }
@ -109,26 +105,33 @@ public class ChangeDeviceInfoUtil {
private static String fetchJsonSafely(String url, String logKey) throws IOException { private static String fetchJsonSafely(String url, String logKey) throws IOException {
String json = null; String json = null;
try { int attemptCount = 0;
json = HttpUtil.requestGet(url);
if (json != null && !json.isEmpty()) {
LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG, "Received " + logKey + ": " + json, null);
return json;
} else {
LogFileUtil.logAndWrite(android.util.Log.WARN, LOG_TAG, "Empty or null response for: " + logKey + ", retrying...", null);
}
} catch (IOException e) {
LogFileUtil.logAndWrite(android.util.Log.WARN, LOG_TAG, "Error fetching " + logKey + ": " + e.getMessage() + ", retrying...", e);
}
// Retry once if the initial attempt failed while (true) {
json = HttpUtil.requestGet(url); attemptCount++;
if (json != null && !json.isEmpty()) { try {
LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG, "Retry success for " + logKey + ": " + json, null); json = HttpUtil.requestGet(url);
return json; if (json != null && !json.isEmpty()) {
} else { LogFileUtil.logAndWrite(android.util.Log.DEBUG, LOG_TAG,
LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Retry failed for " + logKey + ", response is still null or empty.", null); "Received " + logKey + " after " + attemptCount + " attempt(s): " + json, null);
throw new IOException("Failed to fetch valid JSON for " + logKey); return json;
} else {
LogFileUtil.logAndWrite(android.util.Log.WARN, LOG_TAG,
"Empty or null response for: " + logKey + ", retrying in 3 seconds...", null);
}
} catch (IOException e) {
LogFileUtil.logAndWrite(android.util.Log.WARN, LOG_TAG,
"Error fetching " + logKey + " (attempt " + attemptCount + "): " + e.getMessage() + ", retrying in 3 seconds...", e);
}
try {
Thread.sleep(3000);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG,
"Retry interrupted for " + logKey, ie);
throw new IOException("Retry interrupted for " + logKey, ie);
}
} }
} }
@ -243,236 +246,241 @@ public class ChangeDeviceInfoUtil {
} }
public static void changeDeviceInfo(String current_pkg_name, Context context) { public static void changeDeviceInfo(String current_pkg_name, Context context, JSONObject bigoDeviceObject, JSONObject afDeviceObject) {
try{
BigoInfo bigoDevice;
if (bigoDeviceObject != null) {
// BIGO
String cpuClockSpeed = bigoDeviceObject.optString("cpu_clock_speed");
String gaid = bigoDeviceObject.optString("gaid");
String userAgent = bigoDeviceObject.optString("User-Agent");
String osLang = bigoDeviceObject.optString("os_lang");
String osVer = bigoDeviceObject.optString("os_ver");
String tz = bigoDeviceObject.optString("tz");
String systemCountry = bigoDeviceObject.optString("system_country");
String simCountry = bigoDeviceObject.optString("sim_country");
long romFreeIn = bigoDeviceObject.optLong("rom_free_in");
String resolution = bigoDeviceObject.optString("resolution");
String vendor = bigoDeviceObject.optString("vendor");
int batteryScale = bigoDeviceObject.optInt("bat_scale");
// String model = deviceObject.optString("model");
String net = bigoDeviceObject.optString("net");
int dpi = bigoDeviceObject.optInt("dpi");
long romFreeExt = bigoDeviceObject.optLong("rom_free_ext");
String dpiF = bigoDeviceObject.optString("dpi_f");
int cpuCoreNum = bigoDeviceObject.optInt("cpu_core_num");
BigoInfo bigoDevice; bigoDevice = new BigoInfo();
if (bigoDeviceObject != null) { bigoDevice.cpuClockSpeed = cpuClockSpeed;
// BIGO bigoDevice.gaid = gaid;
String cpuClockSpeed = bigoDeviceObject.optString("cpu_clock_speed"); bigoDevice.userAgent = userAgent;
String gaid = bigoDeviceObject.optString("gaid"); bigoDevice.osLang = osLang;
String userAgent = bigoDeviceObject.optString("User-Agent"); bigoDevice.osVer = osVer;
String osLang = bigoDeviceObject.optString("os_lang"); bigoDevice.tz = tz;
String osVer = bigoDeviceObject.optString("os_ver"); bigoDevice.systemCountry = systemCountry;
String tz = bigoDeviceObject.optString("tz"); bigoDevice.simCountry = simCountry;
String systemCountry = bigoDeviceObject.optString("system_country"); bigoDevice.romFreeIn = romFreeIn;
String simCountry = bigoDeviceObject.optString("sim_country"); bigoDevice.resolution = resolution;
long romFreeIn = bigoDeviceObject.optLong("rom_free_in"); bigoDevice.vendor = vendor;
String resolution = bigoDeviceObject.optString("resolution"); bigoDevice.batteryScale = batteryScale;
String vendor = bigoDeviceObject.optString("vendor"); bigoDevice.net = net;
int batteryScale = bigoDeviceObject.optInt("bat_scale"); bigoDevice.dpi = dpi;
// String model = deviceObject.optString("model"); bigoDevice.romFreeExt = romFreeExt;
String net = bigoDeviceObject.optString("net"); bigoDevice.dpiF = dpiF;
int dpi = bigoDeviceObject.optInt("dpi"); bigoDevice.cpuCoreNum = cpuCoreNum;
long romFreeExt = bigoDeviceObject.optLong("rom_free_ext"); TaskUtil.setBigoDevice(bigoDevice);
String dpiF = bigoDeviceObject.optString("dpi_f"); try {
int cpuCoreNum = bigoDeviceObject.optInt("cpu_core_num"); callVCloudSettings_put(current_pkg_name + ".system_country", systemCountry, context);
callVCloudSettings_put(current_pkg_name + ".sim_country", simCountry, context);
bigoDevice = new BigoInfo(); callVCloudSettings_put(current_pkg_name + ".rom_free_in", String.valueOf(romFreeIn), context);
bigoDevice.cpuClockSpeed = cpuClockSpeed; callVCloudSettings_put(current_pkg_name + ".resolution", resolution, context);
bigoDevice.gaid = gaid; callVCloudSettings_put(current_pkg_name + ".vendor", vendor, context);
bigoDevice.userAgent = userAgent; callVCloudSettings_put(current_pkg_name + ".battery_scale", String.valueOf(batteryScale), context);
bigoDevice.osLang = osLang; callVCloudSettings_put(current_pkg_name + ".os_lang", osLang, context);
bigoDevice.osVer = osVer; // callVCloudSettings_put(current_pkg_name + ".model", model, context);
bigoDevice.tz = tz; callVCloudSettings_put(current_pkg_name + ".net", net, context);
bigoDevice.systemCountry = systemCountry; callVCloudSettings_put(current_pkg_name + ".dpi", String.valueOf(dpi), context);
bigoDevice.simCountry = simCountry; callVCloudSettings_put(current_pkg_name + ".rom_free_ext", String.valueOf(romFreeExt), context);
bigoDevice.romFreeIn = romFreeIn; callVCloudSettings_put(current_pkg_name + ".dpi_f", dpiF, context);
bigoDevice.resolution = resolution; callVCloudSettings_put(current_pkg_name + ".cpu_core_num", String.valueOf(cpuCoreNum), context);
bigoDevice.vendor = vendor; callVCloudSettings_put(current_pkg_name + ".cpu_clock_speed", cpuClockSpeed, context);
bigoDevice.batteryScale = batteryScale; callVCloudSettings_put(current_pkg_name + "_gaid", gaid, context);
bigoDevice.net = net; // **User-Agent**
bigoDevice.dpi = dpi; callVCloudSettings_put(current_pkg_name + "_user_agent", userAgent, context);
bigoDevice.romFreeExt = romFreeExt; // **os_lang**系统语言
bigoDevice.dpiF = dpiF; callVCloudSettings_put(current_pkg_name + "_os_lang", osLang, context);
bigoDevice.cpuCoreNum = cpuCoreNum; // **os_ver**
TaskUtil.setBigoDevice(bigoDevice); callVCloudSettings_put(current_pkg_name + "_os_ver", osVer, context);
try { // **tz** (时区)
callVCloudSettings_put(current_pkg_name + ".system_country", systemCountry, context); callVCloudSettings_put(current_pkg_name + "_tz", tz, context);
callVCloudSettings_put(current_pkg_name + ".sim_country", simCountry, context); } catch (Throwable e) {
callVCloudSettings_put(current_pkg_name + ".rom_free_in", String.valueOf(romFreeIn), context); logAndWrite(android.util.Log.ERROR, "ChangeDeviceInfoUtil", "Error occurred while changing device info", e);
callVCloudSettings_put(current_pkg_name + ".resolution", resolution, context); throw new RuntimeException("Error occurred in changeDeviceInfo", e);
callVCloudSettings_put(current_pkg_name + ".vendor", vendor, context);
callVCloudSettings_put(current_pkg_name + ".battery_scale", String.valueOf(batteryScale), context);
callVCloudSettings_put(current_pkg_name + ".os_lang", osLang, context);
// callVCloudSettings_put(current_pkg_name + ".model", model, context);
callVCloudSettings_put(current_pkg_name + ".net", net, context);
callVCloudSettings_put(current_pkg_name + ".dpi", String.valueOf(dpi), context);
callVCloudSettings_put(current_pkg_name + ".rom_free_ext", String.valueOf(romFreeExt), context);
callVCloudSettings_put(current_pkg_name + ".dpi_f", dpiF, context);
callVCloudSettings_put(current_pkg_name + ".cpu_core_num", String.valueOf(cpuCoreNum), context);
callVCloudSettings_put(current_pkg_name + ".cpu_clock_speed", cpuClockSpeed, context);
callVCloudSettings_put(current_pkg_name + "_gaid", gaid, context);
// **User-Agent**
callVCloudSettings_put(current_pkg_name + "_user_agent", userAgent, context);
// **os_lang**系统语言
callVCloudSettings_put(current_pkg_name + "_os_lang", osLang, context);
// **os_ver**
callVCloudSettings_put(current_pkg_name + "_os_ver", osVer, context);
// **tz** (时区)
callVCloudSettings_put(current_pkg_name + "_tz", tz, context);
} catch (Throwable e) {
logAndWrite(android.util.Log.ERROR, "ChangeDeviceInfoUtil", "Error occurred while changing device info", e);
throw new RuntimeException("Error occurred in changeDeviceInfo", e);
}
}
DeviceInfo deviceInfo;
AfInfo afDevice;
if (afDeviceObject != null) {
String advertiserId = afDeviceObject.optString(".advertiserId");
String model = afDeviceObject.optString(".model");
String brand = afDeviceObject.optString(".brand");
String androidId = afDeviceObject.optString(".android_id");
int xPixels = afDeviceObject.optInt(".deviceData.dim.x_px");
int yPixels = afDeviceObject.optInt(".deviceData.dim.y_px");
int densityDpi = afDeviceObject.optInt(".deviceData.dim.d_dpi");
String country = afDeviceObject.optString(".country");
String batteryLevel = afDeviceObject.optString(".batteryLevel");
String stackInfo = Thread.currentThread().getStackTrace()[2].toString();
String product = afDeviceObject.optString(".product");
String network = afDeviceObject.optString(".network");
String langCode = afDeviceObject.optString(".lang_code");
String cpuAbi = afDeviceObject.optString(".deviceData.cpu_abi");
int yDp = afDeviceObject.optInt(".deviceData.dim.ydp");
afDevice = new AfInfo();
afDevice.advertiserId = advertiserId;
afDevice.model = model;
afDevice.brand = brand;
afDevice.androidId = androidId;
afDevice.xPixels = xPixels;
afDevice.yPixels = yPixels;
afDevice.densityDpi = densityDpi;
afDevice.country = country;
afDevice.batteryLevel = batteryLevel;
afDevice.stackInfo = stackInfo;
afDevice.product = product;
afDevice.network = network;
afDevice.langCode = langCode;
afDevice.cpuAbi = cpuAbi;
afDevice.yDp = yDp;
TaskUtil.setAfDevice(afDevice);
String lang = afDeviceObject.optString(".lang");
String ro_product_brand = afDeviceObject.optString("ro.product.brand", "");
String ro_product_model = afDeviceObject.optString("ro.product.model", "");
String ro_product_manufacturer = afDeviceObject.optString("ro.product.manufacturer", "");
String ro_product_device = afDeviceObject.optString("ro.product.device", "");
String ro_product_name = afDeviceObject.optString("ro.product.name", "");
String ro_build_version_incremental = afDeviceObject.optString("ro.build.version.incremental", "");
String ro_build_fingerprint = afDeviceObject.optString("ro.build.fingerprint", "");
String ro_odm_build_fingerprint = afDeviceObject.optString("ro.odm.build.fingerprint", "");
String ro_product_build_fingerprint = afDeviceObject.optString("ro.product.build.fingerprint", "");
String ro_system_build_fingerprint = afDeviceObject.optString("ro.system.build.fingerprint", "");
String ro_system_ext_build_fingerprint = afDeviceObject.optString("ro.system_ext.build.fingerprint", "");
String ro_vendor_build_fingerprint = afDeviceObject.optString("ro.vendor.build.fingerprint", "");
String ro_build_platform = afDeviceObject.optString("ro.board.platform", "");
String persist_sys_cloud_drm_id = afDeviceObject.optString("persist.sys.cloud.drm.id", "");
int persist_sys_cloud_battery_capacity = afDeviceObject.optInt("persist.sys.cloud.battery.capacity", -1);
String persist_sys_cloud_gpu_gl_vendor = afDeviceObject.optString("persist.sys.cloud.gpu.gl_vendor", "");
String persist_sys_cloud_gpu_gl_renderer = afDeviceObject.optString("persist.sys.cloud.gpu.gl_renderer", "");
String persist_sys_cloud_gpu_gl_version = afDeviceObject.optString("persist.sys.cloud.gpu.gl_version", "");
String persist_sys_cloud_gpu_egl_vendor = afDeviceObject.optString("persist.sys.cloud.gpu.egl_vendor", "");
String persist_sys_cloud_gpu_egl_version = afDeviceObject.optString("persist.sys.cloud.gpu.egl_version", "");
String global_android_id = afDeviceObject.optString(".android_id", "");
String anticheck_pkgs = afDeviceObject.optString(".anticheck_pkgs", "");
String pm_list_features = afDeviceObject.optString(".pm_list_features", "");
String pm_list_libraries = afDeviceObject.optString(".pm_list_libraries", "");
String system_http_agent = afDeviceObject.optString("system.http.agent", "");
String webkit_http_agent = afDeviceObject.optString("webkit.http.agent", "");
String com_fk_tools_pkgInfo = afDeviceObject.optString(".pkg_info", "");
String appsflyerKey = afDeviceObject.optString(".appsflyerKey", "");
String appUserId = afDeviceObject.optString(".appUserId", "");
String disk = afDeviceObject.optString(".disk", "");
String operator = afDeviceObject.optString(".operator", "");
String cell_mcc = afDeviceObject.optString(".cell.mcc", "");
String cell_mnc = afDeviceObject.optString(".cell.mnc", "");
String date1 = afDeviceObject.optString(".date1", "");
String date2 = afDeviceObject.optString(".date2", "");
String bootId = afDeviceObject.optString("BootId", "");
deviceInfo = new DeviceInfo();
deviceInfo.lang = lang;
deviceInfo.roProductBrand = ro_product_brand;
deviceInfo.roProductModel = ro_product_model;
deviceInfo.roProductManufacturer = ro_product_manufacturer;
deviceInfo.roProductDevice = ro_product_device;
deviceInfo.roProductName = ro_product_name;
deviceInfo.roBuildVersionIncremental = ro_build_version_incremental;
deviceInfo.roBuildFingerprint = ro_build_fingerprint;
deviceInfo.roOdmBuildFingerprint = ro_odm_build_fingerprint;
deviceInfo.roProductBuildFingerprint = ro_product_build_fingerprint;
deviceInfo.roSystemBuildFingerprint = ro_system_build_fingerprint;
deviceInfo.roSystemExtBuildFingerprint = ro_system_ext_build_fingerprint;
deviceInfo.roVendorBuildFingerprint = ro_vendor_build_fingerprint;
deviceInfo.roBuildPlatform = ro_build_platform;
deviceInfo.persistSysCloudDrmId = persist_sys_cloud_drm_id;
deviceInfo.persistSysCloudBatteryCapacity = persist_sys_cloud_battery_capacity;
deviceInfo.persistSysCloudGpuGlVendor = persist_sys_cloud_gpu_gl_vendor;
deviceInfo.persistSysCloudGpuGlRenderer = persist_sys_cloud_gpu_gl_renderer;
deviceInfo.persistSysCloudGpuGlVersion = persist_sys_cloud_gpu_gl_version;
deviceInfo.persistSysCloudGpuEglVendor = persist_sys_cloud_gpu_egl_vendor;
deviceInfo.persistSysCloudGpuEglVersion = persist_sys_cloud_gpu_egl_version;
TaskUtil.setDeviceInfo(deviceInfo);
try {
callVCloudSettings_put(current_pkg_name + ".advertiserId", advertiserId, context);
callVCloudSettings_put(current_pkg_name + ".model", model, context);
callVCloudSettings_put(current_pkg_name + ".brand", brand, context);
callVCloudSettings_put(current_pkg_name + ".android_id", androidId, context);
callVCloudSettings_put(current_pkg_name + ".lang", lang, context);
callVCloudSettings_put(current_pkg_name + ".country", country, context);
callVCloudSettings_put(current_pkg_name + ".batteryLevel", batteryLevel, context);
callVCloudSettings_put(current_pkg_name + "_screen.optMetrics.stack", stackInfo, context);
callVCloudSettings_put(current_pkg_name + ".product", product, context);
callVCloudSettings_put(current_pkg_name + ".network", network, context);
callVCloudSettings_put(current_pkg_name + ".cpu_abi", cpuAbi, context);
callVCloudSettings_put(current_pkg_name + ".lang_code", langCode, context);
// **广告标识符 (advertiserId)** **启用状态**
boolean isAdIdEnabled = true; // 默认启用广告 ID
callVCloudSettings_put(current_pkg_name + ".advertiserIdEnabled", String.valueOf(isAdIdEnabled), context);
JSONObject displayMetrics = new JSONObject();
displayMetrics.put("widthPixels", xPixels);
displayMetrics.put("heightPixels", yPixels);
displayMetrics.put("densityDpi", densityDpi);
displayMetrics.put("yDp", yDp);
callVCloudSettings_put("screen.device.displayMetrics", displayMetrics.toString(), context);
if (!ShellUtils.hasRootAccess()) {
LogFileUtil.writeLogToFile("ERROR", "ChangeDeviceInfoUtil", "Root access is required to execute system property changes");
} }
// 设置机型, 直接设置属性 bigoDeviceObject = null;
ShellUtils.execRootCmd("setprop ro.product.brand " + ro_product_brand);
ShellUtils.execRootCmd("setprop ro.product.model " + ro_product_model);
ShellUtils.execRootCmd("setprop ro.product.manufacturer " + ro_product_manufacturer);
ShellUtils.execRootCmd("setprop ro.product.device " + ro_product_device);
ShellUtils.execRootCmd("setprop ro.product.name " + ro_product_name);
ShellUtils.execRootCmd("setprop ro.build.version.incremental " + ro_build_version_incremental);
ShellUtils.execRootCmd("setprop ro.build.fingerprint " + ro_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.odm.build.fingerprint " + ro_odm_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.product.build.fingerprint " + ro_product_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.system.build.fingerprint " + ro_system_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.system_ext.build.fingerprint " + ro_system_ext_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.vendor.build.fingerprint " + ro_vendor_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.board.platform " + ro_build_platform);
// Native.setBootId(bootId);
// 修改drm id
ShellUtils.execRootCmd("setprop persist.sys.cloud.drm.id " + persist_sys_cloud_drm_id);
// 电量模拟需要大于1000
ShellUtils.execRootCmd("setprop persist.sys.cloud.battery.capacity " + persist_sys_cloud_battery_capacity);
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_vendor " + persist_sys_cloud_gpu_gl_vendor);
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_renderer " + persist_sys_cloud_gpu_gl_renderer);
// 这个值不能随便改 必须是 OpenGL ES %d.%d 这个格式
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_version " + persist_sys_cloud_gpu_gl_version);
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.egl_vendor " + persist_sys_cloud_gpu_egl_vendor);
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.egl_version " + persist_sys_cloud_gpu_egl_version);
} catch (Throwable e) {
logAndWrite(Log.ERROR, "ChangeDeviceInfoUtil", "Error occurred in changeDeviceInfo", e);
throw new RuntimeException("Error occurred in changeDeviceInfo", e);
} }
DeviceInfo deviceInfo;
AfInfo afDevice;
if (afDeviceObject != null) {
String advertiserId = afDeviceObject.optString(".advertiserId");
String model = afDeviceObject.optString(".model");
String brand = afDeviceObject.optString(".brand");
String androidId = afDeviceObject.optString(".android_id");
int xPixels = afDeviceObject.optInt(".deviceData.dim.x_px");
int yPixels = afDeviceObject.optInt(".deviceData.dim.y_px");
int densityDpi = afDeviceObject.optInt(".deviceData.dim.d_dpi");
String country = afDeviceObject.optString(".country");
String batteryLevel = afDeviceObject.optString(".batteryLevel");
String stackInfo = Thread.currentThread().getStackTrace()[2].toString();
String product = afDeviceObject.optString(".product");
String network = afDeviceObject.optString(".network");
String langCode = afDeviceObject.optString(".lang_code");
String cpuAbi = afDeviceObject.optString(".deviceData.cpu_abi");
int yDp = afDeviceObject.optInt(".deviceData.dim.ydp");
afDevice = new AfInfo();
afDevice.advertiserId = advertiserId;
afDevice.model = model;
afDevice.brand = brand;
afDevice.androidId = androidId;
afDevice.xPixels = xPixels;
afDevice.yPixels = yPixels;
afDevice.densityDpi = densityDpi;
afDevice.country = country;
afDevice.batteryLevel = batteryLevel;
afDevice.stackInfo = stackInfo;
afDevice.product = product;
afDevice.network = network;
afDevice.langCode = langCode;
afDevice.cpuAbi = cpuAbi;
afDevice.yDp = yDp;
TaskUtil.setAfDevice(afDevice);
String lang = afDeviceObject.optString(".lang");
String ro_product_brand = afDeviceObject.optString("ro.product.brand", "");
String ro_product_model = afDeviceObject.optString("ro.product.model", "");
String ro_product_manufacturer = afDeviceObject.optString("ro.product.manufacturer", "");
String ro_product_device = afDeviceObject.optString("ro.product.device", "");
String ro_product_name = afDeviceObject.optString("ro.product.name", "");
String ro_build_version_incremental = afDeviceObject.optString("ro.build.version.incremental", "");
String ro_build_fingerprint = afDeviceObject.optString("ro.build.fingerprint", "");
String ro_odm_build_fingerprint = afDeviceObject.optString("ro.odm.build.fingerprint", "");
String ro_product_build_fingerprint = afDeviceObject.optString("ro.product.build.fingerprint", "");
String ro_system_build_fingerprint = afDeviceObject.optString("ro.system.build.fingerprint", "");
String ro_system_ext_build_fingerprint = afDeviceObject.optString("ro.system_ext.build.fingerprint", "");
String ro_vendor_build_fingerprint = afDeviceObject.optString("ro.vendor.build.fingerprint", "");
String ro_build_platform = afDeviceObject.optString("ro.board.platform", "");
String persist_sys_cloud_drm_id = afDeviceObject.optString("persist.sys.cloud.drm.id", "");
int persist_sys_cloud_battery_capacity = afDeviceObject.optInt("persist.sys.cloud.battery.capacity", -1);
String persist_sys_cloud_gpu_gl_vendor = afDeviceObject.optString("persist.sys.cloud.gpu.gl_vendor", "");
String persist_sys_cloud_gpu_gl_renderer = afDeviceObject.optString("persist.sys.cloud.gpu.gl_renderer", "");
String persist_sys_cloud_gpu_gl_version = afDeviceObject.optString("persist.sys.cloud.gpu.gl_version", "");
String persist_sys_cloud_gpu_egl_vendor = afDeviceObject.optString("persist.sys.cloud.gpu.egl_vendor", "");
String persist_sys_cloud_gpu_egl_version = afDeviceObject.optString("persist.sys.cloud.gpu.egl_version", "");
String global_android_id = afDeviceObject.optString(".android_id", "");
String anticheck_pkgs = afDeviceObject.optString(".anticheck_pkgs", "");
String pm_list_features = afDeviceObject.optString(".pm_list_features", "");
String pm_list_libraries = afDeviceObject.optString(".pm_list_libraries", "");
String system_http_agent = afDeviceObject.optString("system.http.agent", "");
String webkit_http_agent = afDeviceObject.optString("webkit.http.agent", "");
String com_fk_tools_pkgInfo = afDeviceObject.optString(".pkg_info", "");
String appsflyerKey = afDeviceObject.optString(".appsflyerKey", "");
String appUserId = afDeviceObject.optString(".appUserId", "");
String disk = afDeviceObject.optString(".disk", "");
String operator = afDeviceObject.optString(".operator", "");
String cell_mcc = afDeviceObject.optString(".cell.mcc", "");
String cell_mnc = afDeviceObject.optString(".cell.mnc", "");
String date1 = afDeviceObject.optString(".date1", "");
String date2 = afDeviceObject.optString(".date2", "");
String bootId = afDeviceObject.optString("BootId", "");
deviceInfo = new DeviceInfo();
deviceInfo.lang = lang;
deviceInfo.roProductBrand = ro_product_brand;
deviceInfo.roProductModel = ro_product_model;
deviceInfo.roProductManufacturer = ro_product_manufacturer;
deviceInfo.roProductDevice = ro_product_device;
deviceInfo.roProductName = ro_product_name;
deviceInfo.roBuildVersionIncremental = ro_build_version_incremental;
deviceInfo.roBuildFingerprint = ro_build_fingerprint;
deviceInfo.roOdmBuildFingerprint = ro_odm_build_fingerprint;
deviceInfo.roProductBuildFingerprint = ro_product_build_fingerprint;
deviceInfo.roSystemBuildFingerprint = ro_system_build_fingerprint;
deviceInfo.roSystemExtBuildFingerprint = ro_system_ext_build_fingerprint;
deviceInfo.roVendorBuildFingerprint = ro_vendor_build_fingerprint;
deviceInfo.roBuildPlatform = ro_build_platform;
deviceInfo.persistSysCloudDrmId = persist_sys_cloud_drm_id;
deviceInfo.persistSysCloudBatteryCapacity = persist_sys_cloud_battery_capacity;
deviceInfo.persistSysCloudGpuGlVendor = persist_sys_cloud_gpu_gl_vendor;
deviceInfo.persistSysCloudGpuGlRenderer = persist_sys_cloud_gpu_gl_renderer;
deviceInfo.persistSysCloudGpuGlVersion = persist_sys_cloud_gpu_gl_version;
deviceInfo.persistSysCloudGpuEglVendor = persist_sys_cloud_gpu_egl_vendor;
deviceInfo.persistSysCloudGpuEglVersion = persist_sys_cloud_gpu_egl_version;
TaskUtil.setDeviceInfo(deviceInfo);
try {
callVCloudSettings_put(current_pkg_name + ".advertiserId", advertiserId, context);
callVCloudSettings_put(current_pkg_name + ".model", model, context);
callVCloudSettings_put(current_pkg_name + ".brand", brand, context);
callVCloudSettings_put(current_pkg_name + ".android_id", androidId, context);
callVCloudSettings_put(current_pkg_name + ".lang", lang, context);
callVCloudSettings_put(current_pkg_name + ".country", country, context);
callVCloudSettings_put(current_pkg_name + ".batteryLevel", batteryLevel, context);
callVCloudSettings_put(current_pkg_name + "_screen.optMetrics.stack", stackInfo, context);
callVCloudSettings_put(current_pkg_name + ".product", product, context);
callVCloudSettings_put(current_pkg_name + ".network", network, context);
callVCloudSettings_put(current_pkg_name + ".cpu_abi", cpuAbi, context);
callVCloudSettings_put(current_pkg_name + ".lang_code", langCode, context);
// **广告标识符 (advertiserId)** **启用状态**
boolean isAdIdEnabled = true; // 默认启用广告 ID
callVCloudSettings_put(current_pkg_name + ".advertiserIdEnabled", String.valueOf(isAdIdEnabled), context);
JSONObject displayMetrics = new JSONObject();
displayMetrics.put("widthPixels", xPixels);
displayMetrics.put("heightPixels", yPixels);
displayMetrics.put("densityDpi", densityDpi);
displayMetrics.put("yDp", yDp);
callVCloudSettings_put("screen.device.displayMetrics", displayMetrics.toString(), context);
if (!ShellUtils.hasRootAccess()) {
LogFileUtil.writeLogToFile("ERROR", "ChangeDeviceInfoUtil", "Root access is required to execute system property changes");
}
// 设置机型, 直接设置属性
ShellUtils.execRootCmd("setprop ro.product.brand " + ro_product_brand);
ShellUtils.execRootCmd("setprop ro.product.model " + ro_product_model);
ShellUtils.execRootCmd("setprop ro.product.manufacturer " + ro_product_manufacturer);
ShellUtils.execRootCmd("setprop ro.product.device " + ro_product_device);
ShellUtils.execRootCmd("setprop ro.product.name " + ro_product_name);
ShellUtils.execRootCmd("setprop ro.build.version.incremental " + ro_build_version_incremental);
ShellUtils.execRootCmd("setprop ro.build.fingerprint " + ro_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.odm.build.fingerprint " + ro_odm_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.product.build.fingerprint " + ro_product_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.system.build.fingerprint " + ro_system_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.system_ext.build.fingerprint " + ro_system_ext_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.vendor.build.fingerprint " + ro_vendor_build_fingerprint);
ShellUtils.execRootCmd("setprop ro.board.platform " + ro_build_platform);
// Native.setBootId(bootId);
// 修改drm id
ShellUtils.execRootCmd("setprop persist.sys.cloud.drm.id " + persist_sys_cloud_drm_id);
// 电量模拟需要大于1000
ShellUtils.execRootCmd("setprop persist.sys.cloud.battery.capacity " + persist_sys_cloud_battery_capacity);
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_vendor " + persist_sys_cloud_gpu_gl_vendor);
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_renderer " + persist_sys_cloud_gpu_gl_renderer);
// 这个值不能随便改 必须是 OpenGL ES %d.%d 这个格式
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_version " + persist_sys_cloud_gpu_gl_version);
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.egl_vendor " + persist_sys_cloud_gpu_egl_vendor);
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.egl_version " + persist_sys_cloud_gpu_egl_version);
} catch (Throwable e) {
logAndWrite(Log.ERROR, "ChangeDeviceInfoUtil", "Error occurred in changeDeviceInfo", e);
throw new RuntimeException("Error occurred in changeDeviceInfo", e);
}
afDeviceObject = null;
}
} catch (Exception e) {
e.printStackTrace();
} }
} }

View File

@ -0,0 +1,8 @@
package com.example.studyapp.device;
import org.json.JSONObject;
public interface LoadDeviceCallback{
void onLoadDeviceInfo(JSONObject bigoDevice, JSONObject afDevice);
void onLoadDeviceError(String error);
}

View File

@ -0,0 +1,111 @@
package com.example.studyapp.job
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import androidx.core.app.JobIntentService
import com.example.studyapp.autoJS.AutoJsUtil
import com.example.studyapp.device.ChangeDeviceInfoUtil
import com.example.studyapp.device.LoadDeviceCallback
import com.example.studyapp.proxy.ClashUtil
import com.example.studyapp.task.TaskUtil
import com.example.studyapp.update.ChangeCallBack
import com.example.studyapp.update.UpdateUtil.changeDevice
import com.example.studyapp.utils.CountryCode
import com.example.studyapp.utils.IpUtil
import com.example.studyapp.utils.LogFileUtil
import org.json.JSONObject
import java.util.Locale
import java.util.UUID
class ScriptJobService : JobIntentService() {
override fun onHandleWork(intent: Intent) {
execute(callback = object : JobCallback {
override fun onJobFailed() {
Handler(Looper.getMainLooper()).postDelayed({
StartJobService.onEvent(applicationContext)
}, 1000 * 20)
}
})
}
fun execute(callback: JobCallback) {
val taskId = UUID.randomUUID().toString()
runCatching {
ChangeDeviceInfoUtil.getAddDeviceInfo(
CountryCode.currentCountry.uppercase(Locale.getDefault()), CountryCode.DEVICE_TYPE,
object :LoadDeviceCallback {
override fun onLoadDeviceInfo(
bigoDevice: JSONObject?,
afDevice: JSONObject?
) {
// ClashUtil.startProxy(applicationContext)
ClashUtil.switchProxyWithPort(CountryCode.switchCountry())
// ClashUtil.switchProxyGroup("PROXY", "my-socks5-proxy", "http://127.0.0.1:6170")
val geoInfo: String = IpUtil.fetchGeoInfo()
val timeZone: String = IpUtil.getTimeZone(geoInfo)
val packageName = if (TextUtils.isEmpty(name)){
packageName
} else {
name
}
changeDevice(packageName, bigoDevice, afDevice, timeZone, object : ChangeCallBack {
override fun changeSuccess() {
runCatching {
AutoJsUtil.runAutojsScript(applicationContext)
TaskUtil.execSaveTask(
androidId,
taskId,
name,
IpUtil.fetchGeoInfo()
)
TaskUtil.uploadFile(applicationContext, androidId, name)
}.onFailure {
callback.onJobFailed()
}
}
override fun changeFailed() {
LogFileUtil.logAndWrite(
Log.ERROR,
TAG,
"Change device failed",
null
)
callback.onJobFailed()
}
})
}
override fun onLoadDeviceError(error: String?) {
callback.onJobFailed()
}
})
}.onFailure {
callback.onJobFailed()
}
}
companion object {
private const val TAG = "ScriptJobService"
private const val jobId = 102
private const val androidId = "FyZqWrStUvOpKlMn"
private var name = ""
fun onEvent(context: Context, packageName: String) {
name = packageName
enqueueWork(
context,
ScriptJobService::class.java, jobId, Intent(
context,
ScriptJobService::class.java
)
)
}
}
}

View File

@ -0,0 +1,153 @@
package com.example.studyapp.job
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.core.app.JobIntentService
import com.example.studyapp.autoJS.AutoJsUtil
import com.example.studyapp.device.ChangeDeviceInfoUtil
import com.example.studyapp.device.LoadDeviceCallback
import com.example.studyapp.job.ScriptJobService.Companion.onEvent
import com.example.studyapp.proxy.ClashUtil
import com.example.studyapp.update.ChangeCallBack
import com.example.studyapp.update.UpdateUtil.changeDevice
import com.example.studyapp.utils.CountryCode
import com.example.studyapp.utils.IpUtil
import com.example.studyapp.utils.LogFileUtil
import com.example.studyapp.utils.ShellUtils
import com.example.studyapp.utils.ShellUtils.exec
import org.json.JSONObject
import java.util.Locale
/**
* 监听任务
*/
interface JobCallback {
fun onJobFailed()
}
/**
* 这段代码定义了一个继承自 JobIntentService 的后台服务类 StartJobService整体功能如下
* 使用 onHandleWork 处理后台任务防止重复执行并在失败时延迟重启任务
* exec 方法中执行以下操作
* 通过 Root 命令授予应用特殊权限
* 获取并设置设备信息包括国家设备类型等
* 根据国家切换代理配置
* 获取 IP 地理信息和时区
* 修改设备信息若成功则运行 Auto.js 脚本若失败则回调失败方法
* 使用伴生对象管理任务状态与启动逻辑
*/
class StartJobService : JobIntentService() {
/**
* 重写 onHandleWork 方法处理后台任务
* 若任务已在运行则直接返回
* 设置任务状态为运行中
* 执行任务并在任务失败时通过主线程延迟 10 秒后重新触发事件
*/
override fun onHandleWork(intent: Intent) {
if (running) {
return
}
setRunning(true)
exec(
callback = object : JobCallback {
override fun onJobFailed() {
Handler(Looper.getMainLooper()).postDelayed({
onEvent(this@StartJobService)
}, 1000 * 10)
}
}
)
}
/**
* 执行一系列 Root 命令以授予应用特定权限
* 调用 ChangeDeviceInfoUtil 获取并设置设备信息
* 根据国家代码切换代理配置
* 获取 IP 地理信息和时区
* 调用 changeDevice 修改设备信息成功后运行 Auto.js 脚本
* 如果失败回调 onJobFailed 并结束任务
*/
protected fun exec(callback: JobCallback) {
try {
ShellUtils.execRootCmdAndGetResult("pm grant com.example.studyapp android.permission.INTERACT_ACROSS_USERS")
ShellUtils.execRootCmdAndGetResult("pm grant com.example.studyapp android.permission.WRITE_SECURE_SETTINGS")
ShellUtils.execRootCmdAndGetResult("pm setenforce 0")
ChangeDeviceInfoUtil.getAddDeviceInfo(
CountryCode.currentCountry.uppercase(Locale.getDefault()), CountryCode.DEVICE_TYPE,
object : LoadDeviceCallback {
override fun onLoadDeviceInfo(
bigoDevice: JSONObject?,
afDevice: JSONObject?
) {
// ClashUtil.startProxy(applicationContext)
// ClashUtil.switchProxyGroup("PROXY", "DIRECT", "http://127.0.0.1:6170")
ClashUtil.switchProxyWithPort(CountryCode.switchCountry())
// ClashUtil.switchProxyGroup("PROXY", "my-socks5-proxy", "http://127.0.0.1:6170")
val geoInfo: String = IpUtil.fetchGeoInfo()
val timeZone: String = IpUtil.getTimeZone(geoInfo)
changeDevice(packageName, bigoDevice, afDevice, timeZone, object : ChangeCallBack {
override fun changeSuccess() {
AutoJsUtil.runAutojsScript(applicationContext)
setRunning(false)
}
override fun changeFailed() {
LogFileUtil.logAndWrite(
Log.ERROR,
TAG,
"Change device failed",
null
)
callback.onJobFailed()
setRunning(false)
}
})
}
override fun onLoadDeviceError(error: String?) {
callback.onJobFailed()
setRunning(false)
}
})
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* 定义伴生对象包含日志标签任务 ID 和运行状态标志
* 提供 onEvent 方法用于启动后台任务
* 提供 setRunning 方法更新任务运行状态
*/
companion object {
private const val TAG = "StartJobService"
private const val jobId = 101
private var running = false
/**
* onEvent 是一个函数接收 Context 参数
* 使用 enqueueWork 方法启动一个 StartJobService 类型的后台任务
* jobId 是任务的唯一标识符
* 创建了一个 Intent用于指定要启动的服务为 StartJobService
*/
fun onEvent(context: Context) {
enqueueWork(
context,
StartJobService::class.java, jobId, Intent(
context,
StartJobService::class.java
)
)
}
fun setRunning(runningV: Boolean) {
running = runningV
}
}
}

View File

@ -0,0 +1,12 @@
package com.example.studyapp.pad
data class DcInfo(
var area: String = "",
var dcCode: String = "",
var dcName: String = "",
var ossEndpoint: String = "",
var ossEndpointInternal: String = "",
var ossFileEndpoint: String = "",
var ossScreenshotEndpoint: String = ""
)

View File

@ -0,0 +1,13 @@
package com.example.studyapp.pad
import com.android.grape.pad.PageData
data class Pad(
var page: Int = 0,
var pageData: List<PageData> = listOf(),
var rows: Int = 0,
var size: Int = 0,
var total: Int = 0,
var totalPage: Int = 0
)

View File

@ -0,0 +1,8 @@
package com.example.studyapp.pad
data class PadTask(
var padCode: String = "",
var taskId: Int = 0,
var vmStatus: Int = 0
)

View File

@ -0,0 +1,17 @@
package com.android.grape.pad
import com.example.studyapp.pad.DcInfo
data class PageData(
var dataSize: Long = 0,
var dataSizeUsed: Long = 0,
var dcInfo: DcInfo = DcInfo(),
var deviceLevel: String = "",
var deviceStatus: Int = 0,
var imageId: String = "",
var online: Int = 0,
var padCode: String = "",
var padStatus: Int = 0,
var streamStatus: Int = 0
)

View File

@ -0,0 +1,12 @@
package com.example.studyapp.pad
data class TaskDetail(
var endTime: Long = 0,
var errorMsg: String = "",
var padCode: String = "",
var taskContent: Any? = Any(),
var taskId: Int = 0,
var taskResult: Any? = Any(),
var taskStatus: Int = 0
)

View File

@ -4,11 +4,18 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.Environment;
import android.util.Log; import android.util.Log;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import com.example.studyapp.utils.LogFileUtil; import com.example.studyapp.utils.LogFileUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
@ -17,6 +24,9 @@ import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -28,6 +38,18 @@ import org.json.JSONObject;
* @Description: * @Description:
*/ */
public class ClashUtil { public class ClashUtil {
private static final HttpLoggingInterceptor httpLoggingInterceptor= new HttpLoggingInterceptor();
private static final OkHttpClient sharedClient ;
static {
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
sharedClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS) // 连接超时
.readTimeout(30, TimeUnit.SECONDS) // 读取超时
.addInterceptor(httpLoggingInterceptor)
.build();
}
public static void startProxy(Context context) { public static void startProxy(Context context) {
Intent intent = new Intent("com.github.kr328.clash.intent.action.SESSION_CREATE"); Intent intent = new Intent("com.github.kr328.clash.intent.action.SESSION_CREATE");
@ -84,6 +106,60 @@ public class ClashUtil {
context.unregisterReceiver(clashStatusReceiver); context.unregisterReceiver(clashStatusReceiver);
} }
public static int getProxyPort(){
File scriptDir = new File(Environment.getExternalStorageDirectory(), "script");
File portFile = new File(scriptDir, "ip.port.json");
StringBuilder text = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(portFile))) {
String line;
while ((line = br.readLine()) != null) {
text.append(line).append('\n');
}
} catch (IOException e) {
Log.e("TAG", "getProxyPort: ", e);
return -1;
}
int port = -1;
try{
Log.d("TAG", "getProxyPort: "+text);
JSONObject config = new JSONObject(text.toString());
port = config.optInt("port", -1);
}catch (Exception e){
Log.e("TAG", "getProxyPort: ", e);
}
return port;
}
public static void switchProxyWithPort(String country) {
int port = getProxyPort();
// 安全构建 URL
HttpUrl url = HttpUrl.parse("http://39.103.73.250/tt/test/testProxy.jsp")
.newBuilder()
.addQueryParameter("port", port+"")
.addQueryParameter("country", country)
.build();
Request request = new Request.Builder()
.url(url)
.build();
// 使用 try-with-resources 确保 Response 自动关闭
try (Response response = sharedClient.newCall(request).execute()) {
// 读取并记录响应内容
String responseBody = response.body() != null ? response.body().string() : "Empty response body";
if (response.isSuccessful()) {
LogFileUtil.logAndWrite(Log.INFO, "ClashUtil",
"switchProxyGroup: Success | Status: " + response.code() + " | Response: " + responseBody, null);
} else {
LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil",
"switchProxyGroup: Failed | Status: " + response.code() + " | Response: " + responseBody, null);
}
} catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Unexpected error", e);
}
}
public static void switchProxyGroup(String groupName, String proxyName, String controllerUrl) { public static void switchProxyGroup(String groupName, String proxyName, String controllerUrl) {
if (groupName == null || groupName.trim().isEmpty() || proxyName == null || proxyName.trim().isEmpty()) { if (groupName == null || groupName.trim().isEmpty() || proxyName == null || proxyName.trim().isEmpty()) {
LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Invalid arguments", null); LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Invalid arguments", null);
@ -116,26 +192,20 @@ public class ClashUtil {
.put(requestBody) .put(requestBody)
.build(); .build();
client.newCall(request).enqueue(new Callback() { try {
@Override Response response = client.newCall(request).execute();
public void onFailure(Call call, IOException e) {
LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Failed to switch proxy", e); if (response.isSuccessful() && response.body() != null) {
System.out.println("Failed to switch proxy: " + e.getMessage()); LogFileUtil.logAndWrite(Log.INFO, "ClashUtil", "switchProxyGroup: Switch proxy response", null);
} else {
LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Response is not successful or body is null", null);
} }
@Override response.close();
public void onResponse(Call call, Response response) throws IOException { } catch (IOException e) {
try { LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Failed to switch proxy", e);
if (response.body() != null) { System.out.println("Failed to switch proxy: " + e.getMessage());
LogFileUtil.logAndWrite(Log.INFO, "ClashUtil", "switchProxyGroup: Switch proxy response", null); }
} else {
LogFileUtil.logAndWrite(Log.ERROR, "ClashUtil", "switchProxyGroup: Response body is null", null);
}
} finally {
response.close();
}
}
});
} }
} }

View File

@ -16,4 +16,8 @@ public class AfInfo {
public String langCode; public String langCode;
public String cpuAbi; public String cpuAbi;
public long yDp; public long yDp;
public String toString() {
return "advertiserId=" + advertiserId + ", model=" + model + ", brand=" + brand + ", androidId=" + androidId + ", xPixels=" + xPixels + ", yPixels=" + yPixels + ", densityDpi=" + densityDpi + ", country=" + country + ", batteryLevel=" + batteryLevel + ", stackInfo=" + stackInfo + ", product=" + product + ", network=" + network + ", langCode=" + langCode + ", cpuAbi=" + cpuAbi + ", yDp=" + yDp;
}
} }

View File

@ -1,5 +1,7 @@
package com.example.studyapp.task; package com.example.studyapp.task;
import androidx.annotation.NonNull;
// 使用 JSON 库动态生成 JSON 请求体 (使用 Gson 示例) // 使用 JSON 库动态生成 JSON 请求体 (使用 Gson 示例)
public class BigoInfo { public class BigoInfo {
public String cpuClockSpeed; public String cpuClockSpeed;
@ -19,4 +21,28 @@ public class BigoInfo {
public long romFreeExt; public long romFreeExt;
public String dpiF; public String dpiF;
public long cpuCoreNum; public long cpuCoreNum;
@NonNull
@Override
public String toString() {
return "BigoInfo{" +
"cpuClockSpeed='" + cpuClockSpeed + '\'' +
", gaid='" + gaid + '\'' +
", userAgent='" + userAgent + '\'' +
", osLang='" + osLang + '\'' +
", osVer='" + osVer + '\'' +
", tz='" + tz + '\'' +
", systemCountry='" + systemCountry + '\'' +
", simCountry='" + simCountry + '\'' +
", romFreeIn=" + romFreeIn +
", resolution='" + resolution + '\'' +
", vendor='" + vendor + '\'' +
", batteryScale=" + batteryScale +
", net='" + net + '\'' +
", dpi=" + dpi +
", romFreeExt=" + romFreeExt +
", dpiF='" + dpiF + '\'' +
", cpuCoreNum=" + cpuCoreNum +
'}';
}
} }

View File

@ -1,5 +1,7 @@
package com.example.studyapp.task; package com.example.studyapp.task;
import androidx.annotation.NonNull;
public class DeviceInfo { public class DeviceInfo {
public String lang; public String lang;
@ -23,4 +25,32 @@ public class DeviceInfo {
public String persistSysCloudGpuGlVersion; public String persistSysCloudGpuGlVersion;
public String persistSysCloudGpuEglVendor; public String persistSysCloudGpuEglVendor;
public String persistSysCloudGpuEglVersion; public String persistSysCloudGpuEglVersion;
@NonNull
@Override
public String toString() {
return "DeviceInfo{" +
"lang='" + lang + '\'' +
", roProductBrand='" + roProductBrand + '\'' +
", roProductModel='" + roProductModel + '\'' +
", roProductManufacturer='" + roProductManufacturer + '\'' +
", roProductDevice='" + roProductDevice + '\'' +
", roProductName='" + roProductName + '\'' +
", roBuildVersionIncremental='" + roBuildVersionIncremental + '\'' +
", roBuildFingerprint='" + roBuildFingerprint + '\'' +
", roOdmBuildFingerprint='" + roOdmBuildFingerprint + '\'' +
", roProductBuildFingerprint='" + roProductBuildFingerprint + '\'' +
", roSystemBuildFingerprint='" + roSystemBuildFingerprint + '\'' +
", roSystemExtBuildFingerprint='" + roSystemExtBuildFingerprint + '\'' +
", roVendorBuildFingerprint='" + roVendorBuildFingerprint + '\'' +
", roBuildPlatform='" + roBuildPlatform + '\'' +
", persistSysCloudDrmId='" + persistSysCloudDrmId + '\'' +
", persistSysCloudBatteryCapacity=" + persistSysCloudBatteryCapacity +
", persistSysCloudGpuGlVendor='" + persistSysCloudGpuGlVendor + '\'' +
", persistSysCloudGpuGlRenderer='" + persistSysCloudGpuGlRenderer + '\'' +
", persistSysCloudGpuGlVersion='" + persistSysCloudGpuGlVersion + '\'' +
", persistSysCloudGpuEglVendor='" + persistSysCloudGpuEglVendor + '\'' +
", persistSysCloudGpuEglVersion='" + persistSysCloudGpuEglVersion + '\'' +
'}';
}
} }

View File

@ -1,15 +1,13 @@
package com.example.studyapp.task; package com.example.studyapp.task;
import static androidx.core.content.PackageManagerCompat.LOG_TAG;
import android.content.Context; import android.content.Context;
import android.os.Environment;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.example.studyapp.utils.FileUtils;
import com.example.studyapp.utils.LogFileUtil; import com.example.studyapp.utils.LogFileUtil;
import com.example.studyapp.utils.ShellUtils; import com.example.studyapp.utils.ShellUtils;
import com.google.android.gms.common.util.CollectionUtils; import com.example.studyapp.utils.ZipUtils;
import com.google.android.gms.common.util.MapUtils;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
@ -18,15 +16,12 @@ import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.HttpUrl.Builder;
import okhttp3.MediaType; import okhttp3.MediaType;
import okhttp3.MultipartBody; import okhttp3.MultipartBody;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@ -34,7 +29,6 @@ import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -61,7 +55,7 @@ public class TaskUtil {
.readTimeout(30, TimeUnit.SECONDS) // 读取超时 .readTimeout(30, TimeUnit.SECONDS) // 读取超时
.build(); .build();
public static void postDeviceInfo(String androidId, String taskId,String packageName) { public static void postDeviceInfo(String androidId, String taskId,String packageName, String ipInfo) {
Log.i("TaskUtil", "postDeviceInfo called with androidId: " + androidId); Log.i("TaskUtil", "postDeviceInfo called with androidId: " + androidId);
if (okHttpClient == null) { if (okHttpClient == null) {
@ -69,33 +63,28 @@ public class TaskUtil {
throw new IllegalStateException("HttpClient is not initialized"); throw new IllegalStateException("HttpClient is not initialized");
} }
if (BASE_URL == null || BASE_URL.isEmpty()) { Log.d("TaskUtil", "Creating payload for the request...");
LogFileUtil.logAndWrite(android.util.Log.ERROR, "TaskUtil", "BASE_URL is not initialized", null);
throw new IllegalStateException("BASE_URL is not initialized");
}
Log.d("TaskUtil", "Creating payload for the request...");
Payload payload = new Payload(); Payload payload = new Payload();
payload.bigoDeviceObject = bigoDevice; payload.bigoDeviceObject = bigoDevice;
payload.afDeviceObject = afDevice; payload.afDeviceObject = afDevice;
payload.other = deviceInfo; payload.other = deviceInfo;
Gson gson = new GsonBuilder().serializeNulls().create(); Gson gson = new GsonBuilder().serializeNulls().create();
String jsonRequestBody = gson.toJson(payload); String jsonRequestBody = gson.toJson(payload);
Log.d("TaskUtil", "Request payload: " + jsonRequestBody); Log.d("TaskUtil", "Request payload: " + jsonRequestBody);
if (packageName == null){ Builder urlBuilder = HttpUrl.parse(BASE_URL)
packageName = "";
}
HttpUrl url = HttpUrl.parse(BASE_URL)
.newBuilder() .newBuilder()
.addPathSegment("device_info_upload") .addPathSegment("device_info_upload")
.addQueryParameter("id", androidId) .addQueryParameter("id", androidId)
.addQueryParameter("taskId", taskId) .addQueryParameter("taskId", taskId)
.addQueryParameter("packageName", packageName) .addQueryParameter("deviceIp",ipInfo);
.build();
if (!TextUtils.isEmpty(packageName)){
urlBuilder.addQueryParameter("packageName", packageName);
}
HttpUrl url = urlBuilder.build();
Log.d("TaskUtil", "Request URL: " + url.toString()); Log.d("TaskUtil", "Request URL: " + url.toString());
RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"), jsonRequestBody); RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"), jsonRequestBody);
@ -188,13 +177,13 @@ public class TaskUtil {
} }
public static void infoUpload(Context context, String androidId, String packAge) throws IOException { public static void uploadFile(Context context, String androidId, String packAge) throws IOException {
Log.i("TaskUtil", "infoUpload called with androidId: " + androidId + ", package: " + packAge); Log.i("TaskUtil", "infoUpload called with androidId: " + androidId + ", package: " + packAge);
if (packAge == null || packAge.isEmpty()) { if (packAge == null || packAge.isEmpty()) {
LogFileUtil.logAndWrite(android.util.Log.ERROR, "TaskUtil", "Package name is null or empty", null); LogFileUtil.logAndWrite(android.util.Log.ERROR, "TaskUtil", "Package name is null or empty", null);
throw new IllegalArgumentException("Package name cannot be null or empty"); return;
} }
if (context == null) { if (context == null) {
@ -224,11 +213,12 @@ public class TaskUtil {
if (zipFile.exists()) { if (zipFile.exists()) {
delFileSh(zipFile.getAbsolutePath()); delFileSh(zipFile.getAbsolutePath());
} }
File copiedAPKFile = new File(context.getCacheDir(), packAge+"_upload.apk"); File copiedAPKFile = new File(context.getCacheDir(), packAge);
if (copiedAPKFile.exists()) { if (copiedAPKFile.exists()) {
delFileSh(copiedAPKFile.getAbsolutePath()); delFileSh(copiedAPKFile.getAbsolutePath());
} }
copyFolderSh(apkSourceFile, copiedAPKFile.getAbsolutePath()); String parentPath = FileUtils.getParentDirectory(apkSourceFile);
copyFolderSh(parentPath, copiedAPKFile.getAbsolutePath());
// boolean success = clearUpFileInDst(copiedDir); // boolean success = clearUpFileInDst(copiedDir);
// if (success) { // if (success) {
// // 压缩APK文件 // // 压缩APK文件
@ -236,20 +226,29 @@ public class TaskUtil {
// } // }
// 压缩APK文件 // 压缩APK文件
compressToZip(copiedAPKFile, zipFile); // compressToZip(copiedAPKFile, zipFile);
try {
ZipUtils.zipDirectory(copiedAPKFile.getAbsolutePath(), zipFile.getAbsolutePath());
}catch (Exception e){
zipFile.delete();
e.printStackTrace();
}
//uninstall
String uninstall = "pm uninstall "+packAge;
String chmodResult = ShellUtils.execRootCmdAndGetResult(uninstall);
Log.e("TAG", "infoUpload compress finish: ");
// 上传压缩文件 // 上传压缩文件
if (!zipFile.exists()) { if (!zipFile.exists()) {
Log.w("TaskUtil", "Upload file does not exist: " + outputZipPath); Log.w("TaskUtil", "Upload file does not exist: " + outputZipPath);
return; return;
} }
String safeNewPath = zipFile.getAbsolutePath().replace(" ", "\\ ").replace("\"", "\\\"");
String chmod = "chmod 777 \"" + safeNewPath + "\"";
uploadFile(zipFile); uploadFile(zipFile);
//uninstall
String uninstall = "pm uninstall "+packAge;
String chmodResult = ShellUtils.execRootCmdAndGetResult(uninstall);
// 清理临时文件 // 清理临时文件
delFileSh(copiedAPKFile.getAbsolutePath()); delFileSh(copiedAPKFile.getAbsolutePath());
ShellUtils.execRootCmdAndGetResult(chmod);
delFileSh(zipFile.getAbsolutePath()); delFileSh(zipFile.getAbsolutePath());
} }
@ -282,6 +281,7 @@ public class TaskUtil {
String result = ShellUtils.execRootCmdAndGetResult(cmd); String result = ShellUtils.execRootCmdAndGetResult(cmd);
String chmod = "chmod 777 \"" + safeNewPath + "\""; String chmod = "chmod 777 \"" + safeNewPath + "\"";
String chmodResult = ShellUtils.execRootCmdAndGetResult(chmod); String chmodResult = ShellUtils.execRootCmdAndGetResult(chmod);
recursiveChmod777(dst);
// if (!TextUtils.isEmpty(chmodResult)) { // if (!TextUtils.isEmpty(chmodResult)) {
LogFileUtil.logAndWrite(android.util.Log.ERROR, "TaskUtil", "chmodResult. Result: " + chmodResult, null); LogFileUtil.logAndWrite(android.util.Log.ERROR, "TaskUtil", "chmodResult. Result: " + chmodResult, null);
// return false; // return false;
@ -299,12 +299,37 @@ public class TaskUtil {
} }
} }
public static void recursiveChmod777(File dir) {
if (dir == null || !dir.exists()) {
Log.e("Chmod", "目录不存在或为null");
return;
}
// 先修改当前目录权限
String currentPath = dir.getAbsolutePath().replace(" ", "\\ ").replace("\"", "\\\"");
String chmodCmd = "chmod 777 \"" + currentPath + "\"";
ShellUtils.execRootCmdAndGetResult(chmodCmd);
// 递归处理子项
File[] children = dir.listFiles();
if (children != null) {
for (File child : children) {
if (child.isDirectory()) {
recursiveChmod777(child); // 递归处理子目录
} else {
String filePath = child.getAbsolutePath().replace(" ", "\\ ").replace("\"", "\\\"");
chmodCmd = "chmod 777 \"" + filePath + "\"";
ShellUtils.execRootCmdAndGetResult(chmodCmd);
}
}
}
}
/** /**
*在给定的目标目录中清除特定的文件和目录 *在给定的目标目录中清除特定的文件和目录
*子目录未命名为缓存并且删除了大于3 MB的文件 *子目录未命名为缓存并且删除了大于3 MB的文件
*记录保留的文件和目录的路径 *记录保留的文件和目录的路径
* *
* @param DST将处理其文件和子目录的目标目录
* @return true如果目的目录存在并且已成功处理则为false否则 * @return true如果目的目录存在并且已成功处理则为false否则
*/ */
private static boolean clearUpFileInDst(File dst) { private static boolean clearUpFileInDst(File dst) {
@ -742,9 +767,10 @@ public class TaskUtil {
return getDeviceInfoSync(androidId,taskId); return getDeviceInfoSync(androidId,taskId);
} }
public static void execSaveTask(Context context, String androidId, String taskId,String packName) { public static void execSaveTask(String androidId, String taskId,String packName, String ipInfo) {
if (context == null) { if (packName == null || packName.isEmpty()) {
throw new IllegalArgumentException("Context or Package name cannot be null or empty"); LogFileUtil.logAndWrite(Log.ERROR,"TaskUtil", "Package name is null or empty", null);
return;
} }
if (androidId == null || androidId.isEmpty()) { if (androidId == null || androidId.isEmpty()) {
@ -753,7 +779,7 @@ public class TaskUtil {
} }
try { try {
postDeviceInfo(androidId, taskId,packName); postDeviceInfo(androidId, taskId,packName,ipInfo);
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error in execReloginTask: " + e.getMessage()); System.err.println("Error in execReloginTask: " + e.getMessage());
e.printStackTrace(); e.printStackTrace();

View File

@ -0,0 +1,76 @@
package com.example.studyapp.update
import android.util.Log
import com.example.studyapp.pad.Pad
import com.example.studyapp.pad.PadTask
import com.example.studyapp.pad.TaskDetail
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import org.json.JSONArray
import org.json.JSONObject
import kotlin.apply
import kotlin.collections.isNotEmpty
import kotlin.to
import kotlin.toString
object Api {
private const val TAG = "Api"
const val UPDATE_PAD: String = "/openapi/open/pad/updatePadProperties"
const val PAD_DETAIL: String = "/openapi/open/pad/padDetails"
const val PAD_TASK: String = "/task-center/open/task/padTaskDetail"
fun padDetail(): ApiResponse<Pad>{
val param = Gson().toJson(
mapOf(
"page" to 1,
"rows" to 10,
"padCode" to listOf("ACP250702PWJCTLF")
)
)
val (response, code) = HttpUtils.postSync(PAD_DETAIL, param)
if (code == 200) {
Log.d("padDetail", response.toString())
var apiResponse: ApiResponse<Pad> = Gson().fromJson(response, object : TypeToken<ApiResponse<Pad>>() {}.type)
return apiResponse
} else {
Log.d("padDetail", "error: $code")
return ApiResponse(code, "error", 0, null)
}
}
fun updatePad(params: String): ApiResponseList<PadTask>{
val (response, code) = HttpUtils.postSync(UPDATE_PAD, params)
if (code == 200) {
Log.d("updatePad", response.toString())
var apiResponse: ApiResponseList<PadTask> = Gson().fromJson(response, object : TypeToken<ApiResponseList<PadTask>>() {}.type)
return apiResponse
} else {
Log.d("updatePad", "error: $code")
return ApiResponseList(code, "error", 0, emptyList())
}
}
fun padTaskDetail(taskId: Int): Int{
val jsonString = JSONObject().apply {
put("taskIds", JSONArray().apply {
put(taskId)
})
}.toString()
Log.d(TAG, "padTaskDetail: $jsonString")
val (response, code) = HttpUtils.postSync(PAD_TASK, jsonString)
if (code == 200) {
Log.d("padTaskDetail", response.toString())
var apiResponse: ApiResponseList<TaskDetail> = Gson().fromJson(response, object : TypeToken<ApiResponseList<TaskDetail>>() {}.type)
val taskList = apiResponse.data
if (apiResponse.isSuccess() && taskList!= null && taskList.isNotEmpty()){
val task = taskList[0]
return task.taskStatus
}
return -1
}else {
Log.d("padTaskDetail", "error: $code")
return -1
}
}
}

View File

@ -0,0 +1,23 @@
package com.example.studyapp.update
data class ApiResponse<T>(
val code: Int,
val message: String,
val ts: Long,
var data: T? = null
){
fun isSuccess(): Boolean {
return code == 200
}
}
data class ApiResponseList<T>(
val code: Int,
val message: String,
val ts: Long,
var data: List<T>? = null
){
fun isSuccess(): Boolean {
return code == 200
}
}

View File

@ -0,0 +1,30 @@
package com.example.studyapp.update;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class ArmCloudSignatureV2 {
public static final String ALGORITHM = "HmacSHA256";
public static final String SECRET_KEY = "gz8f1u0t63byzdu6ozbx8r5qs3e5lipt";
public static final String SECRET_ID = "3yc8c8bg1dym0zaiwjh867al";
public static String calculateSignature(String timestamp, String path, String body) throws Exception {
String stringToSign = timestamp + path + (body != null ? body : "");
Mac hmacSha256 = Mac.getInstance(ALGORITHM);
SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_ID.getBytes(StandardCharsets.UTF_8), ALGORITHM);
hmacSha256.init(secretKeySpec);
byte[] hash = hmacSha256.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hash);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}

View File

@ -0,0 +1,6 @@
package com.example.studyapp.update
interface ChangeCallBack {
fun changeSuccess()
fun changeFailed()
}

View File

@ -0,0 +1,258 @@
package com.example.studyapp.update
import android.util.Log
import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.logging.HttpLoggingInterceptor
import java.io.IOException
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
object HttpUtils {
const val HOST: String = "https://openapi-hk.armcloud.net"
private val client: OkHttpClient by lazy {
val trustAllCerts: Array<TrustManager> = arrayOf<TrustManager>(object : X509TrustManager {
override fun checkClientTrusted(
chain: Array<X509Certificate?>?,
authType: String?
) {
}
override fun checkServerTrusted(
chain: Array<X509Certificate?>?,
authType: String?
) {
}
override fun getAcceptedIssuers(): Array<X509Certificate?>? {
return arrayOf<X509Certificate?>()
}
}
)
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
.hostnameVerifier(HostnameVerifier { _, _ -> true })
.build()
}
// JSON媒体类型
private val JSON_MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull()
// 回调接口
interface HttpCallback {
fun onSuccess(response: String, code: Int)
fun onFailure(error: String, code: Int?)
}
/**
* GET 请求异步
*
* @param url 请求URL
* @param params 查询参数可选
* @param headers 请求头可选
* @param callback 回调接口
*/
fun getAsync(
url: String,
params: Map<String, String>? = null,
callback: HttpCallback
) {
val request = buildGetRequest(url, params)
executeRequestAsync(request, callback)
}
/**
* POST 请求异步
*
* @param url 请求URL
* @param body 请求体JSON格式
* @param headers 请求头可选
* @param callback 回调接口
*/
fun postAsync(
url: String,
body: String? = null,
callback: HttpCallback
) {
val request = buildPostRequest(url, body)
executeRequestAsync(request, callback)
}
/**
* GET 请求同步
*
* @param url 请求URL
* @param params 查询参数可选
* @param headers 请求头可选
* @return Pair<响应内容, 状态码>
*/
fun getSync(
url: String,
params: Map<String, String>? = null,
): Pair<String?, Int> {
val request = buildGetRequest(url, params)
return executeRequestSync(request)
}
/**
* POST 请求同步
*
* @param url 请求URL
* @param body 请求体JSON格式
* @param headers 请求头可选
* @return Pair<响应内容, 状态码>
*/
fun postSync(
url: String,
body: String? = null
): Pair<String?, Int> {
val request = buildPostRequest(url, body)
return executeRequestSync(request)
}
/**
* 取消所有请求
*/
fun cancelAllRequests() {
client.dispatcher.cancelAll()
}
// 内部方法 --------------------------------
private fun buildGetRequest(
path: String ,
params: Map<String, String>?,
): Request {
val url = "$HOST$path"
val httpUrlBuilder = url.toHttpUrlOrNull()?.newBuilder()
?: throw IllegalArgumentException("Invalid URL: $url")
var param = ""
params?.forEach { (key, value) ->
httpUrlBuilder.addQueryParameter(key, value)
param += "&${key}=${value}"
}
if (param.isNotEmpty()){
param = param.substring(1)
}
val requestBuilder = Request.Builder().url(httpUrlBuilder.build())
val authver = "2.0"
val timestamp = System.currentTimeMillis()
val sign =
ArmCloudSignatureV2.calculateSignature(timestamp.toString(), path, param)
addHeaders(
requestBuilder,
mapOf(
"authver" to authver,
"x-ak" to ArmCloudSignatureV2.SECRET_KEY,
"x-timestamp" to timestamp.toString(),
"x-sign" to sign
)
)
return requestBuilder.build()
}
private fun buildPostRequest(
path: String,
body: String? = null
): Request {
val url = "$HOST$path"
val bodyString = body?:""
val requestBuilder = Request.Builder()
.url(url)
.post(bodyString.toRequestBody(JSON_MEDIA_TYPE))
val authver = "2.0"
val timestamp = System.currentTimeMillis()
val sign =
ArmCloudSignatureV2.calculateSignature(timestamp.toString(), path, body)
addHeaders(
requestBuilder,
mapOf(
"authver" to authver,
"x-ak" to ArmCloudSignatureV2.SECRET_KEY,
"x-timestamp" to timestamp.toString(),
"x-sign" to sign
)
)
return requestBuilder.build()
}
private fun addHeaders(
builder: Request.Builder,
headers: Map<String, String>
) {
headers.forEach { (key, value) ->
builder.addHeader(key, value)
}
}
private fun buildFormBody(formData: Map<String, String>): RequestBody {
val formBodyBuilder = FormBody.Builder()
formData.forEach { (key, value) ->
formBodyBuilder.add(key, value)
}
return formBodyBuilder.build()
}
private fun executeRequestAsync(
request: Request,
callback: HttpCallback
) {
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val responseBody = response.body?.string()
val code = response.code
if (response.isSuccessful && responseBody != null) {
callback.onSuccess(responseBody, code)
} else {
callback.onFailure(
responseBody ?: "Empty response",
code
)
}
}
override fun onFailure(call: Call, e: IOException) {
callback.onFailure(e.message ?: "Unknown network error", null)
}
})
}
private fun executeRequestSync(request: Request): Pair<String?, Int> {
return try {
val response = client.newCall(request).execute()
val responseBody = response.peekBody(Long.MAX_VALUE).string()
val code = response.code
Log.d("TAG", "executeRequestSync: $responseBody")
if (response.isSuccessful && responseBody.isNotEmpty()) {
Pair(responseBody, code)
} else {
Pair(null, -1)
}
} catch (e: IOException) {
Pair(null, -1) // 网络错误状态码
}
}
}

View File

@ -0,0 +1,318 @@
package com.example.studyapp.update
import android.util.Log
import com.example.studyapp.task.AfInfo
import com.example.studyapp.task.BigoInfo
import com.example.studyapp.task.DeviceInfo
import com.example.studyapp.task.TaskUtil
import com.example.studyapp.utils.ShellUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
object UpdateUtil {
val scope = CoroutineScope(Dispatchers.IO)
fun changeDevice(
recordPackageName: String,
bigoDeviceObject: JSONObject?,
afDeviceObject: JSONObject?,
time: String,
callback: ChangeCallBack
) {
try {
val padCode = ShellUtils.execRootCmdAndGetResult("getprop ro.boot.pad_code")
Log.d("TAG", "changeDevice: $padCode")
val jsonObject = JSONObject().apply {
put("padCodes", JSONArray().apply {
put(padCode)
})
}
var timeZone: String = ""
bigoDeviceObject?.apply {
val cpuClockSpeed: String = bigoDeviceObject.optString("cpu_clock_speed")
val gaid: String = bigoDeviceObject.optString("gaid")
val userAgent: String = bigoDeviceObject.optString("User-Agent")
val osLang: String = bigoDeviceObject.optString("os_lang")
val osVer: String = bigoDeviceObject.optString("os_ver")
timeZone = bigoDeviceObject.optString("tz")
val systemCountry: String = bigoDeviceObject.optString("system_country")
val simCountry: String = bigoDeviceObject.optString("sim_country")
val romFreeIn: Long = bigoDeviceObject.optLong("rom_free_in")
val resolution: String = bigoDeviceObject.optString("resolution")
val vendor: String = bigoDeviceObject.optString("vendor")
val batteryScale: Int = bigoDeviceObject.optInt("bat_scale")
val net: String = bigoDeviceObject.optString("net")
val dpi: Int = bigoDeviceObject.optInt("dpi")
val romFreeExt: Long = bigoDeviceObject.optLong("rom_free_ext")
val dpiF: String = bigoDeviceObject.optString("dpi_f")
val cpuCoreNum: Int = bigoDeviceObject.optInt("cpu_core_num")
val bigoDevice = BigoInfo()
bigoDevice.cpuClockSpeed = cpuClockSpeed
bigoDevice.gaid = gaid
bigoDevice.userAgent = userAgent
bigoDevice.osLang = osLang
bigoDevice.osVer = osVer
bigoDevice.tz = timeZone
bigoDevice.systemCountry = systemCountry
bigoDevice.simCountry = simCountry
bigoDevice.romFreeIn = romFreeIn
bigoDevice.resolution = resolution
bigoDevice.vendor = vendor
bigoDevice.batteryScale = batteryScale
bigoDevice.net = net
bigoDevice.dpi = dpi.toLong()
bigoDevice.romFreeExt = romFreeExt
bigoDevice.dpiF = dpiF
bigoDevice.cpuCoreNum = cpuCoreNum.toLong()
TaskUtil.setBigoDevice(bigoDevice)
}
afDeviceObject?.apply {
val advertiserId = afDeviceObject.optString(".advertiserId")
val model = afDeviceObject.optString(".model")
val brand = afDeviceObject.optString(".brand")
val androidId = afDeviceObject.optString(".android_id")
val xPixels = afDeviceObject.optInt(".deviceData.dim.x_px")
val yPixels = afDeviceObject.optInt(".deviceData.dim.y_px")
val densityDpi = afDeviceObject.optInt(".deviceData.dim.d_dpi")
val country = afDeviceObject.optString(".country")
val batteryLevel = afDeviceObject.optString(".batteryLevel")
val stackInfo = Thread.currentThread().getStackTrace()[2].toString()
val product = afDeviceObject.optString(".product")
val network = afDeviceObject.optString(".network")
val langCode = afDeviceObject.optString(".lang_code")
val cpuAbi = afDeviceObject.optString(".deviceData.cpu_abi")
val yDp = afDeviceObject.optInt(".deviceData.dim.ydp")
val lang = afDeviceObject.optString(".lang")
val ro_product_brand = afDeviceObject.optString("ro.product.brand", "")
val ro_product_model = afDeviceObject.optString("ro.product.model", "")
val ro_product_manufacturer =
afDeviceObject.optString("ro.product.manufacturer", "")
val ro_product_device = afDeviceObject.optString("ro.product.device", "")
val ro_product_name = afDeviceObject.optString("ro.product.name", "")
val ro_build_version_incremental =
afDeviceObject.optString("ro.build.version.incremental", "")
val ro_build_fingerprint = afDeviceObject.optString("ro.build.fingerprint", "")
val ro_odm_build_fingerprint =
afDeviceObject.optString("ro.odm.build.fingerprint", "")
val ro_product_build_fingerprint =
afDeviceObject.optString("ro.product.build.fingerprint", "")
val ro_system_build_fingerprint =
afDeviceObject.optString("ro.system.build.fingerprint", "")
val ro_system_ext_build_fingerprint =
afDeviceObject.optString("ro.system_ext.build.fingerprint", "")
val ro_vendor_build_fingerprint =
afDeviceObject.optString("ro.vendor.build.fingerprint", "")
val ro_build_platform = afDeviceObject.optString("ro.board.platform", "")
val persist_sys_cloud_drm_id =
afDeviceObject.optString("persist.sys.cloud.drm.id", "")
val persist_sys_cloud_battery_capacity =
afDeviceObject.optInt("persist.sys.cloud.battery.capacity", -1)
val persist_sys_cloud_gpu_gl_vendor =
afDeviceObject.optString("persist.sys.cloud.gpu.gl_vendor", "")
val persist_sys_cloud_gpu_gl_renderer =
afDeviceObject.optString("persist.sys.cloud.gpu.gl_renderer", "")
val persist_sys_cloud_gpu_gl_version =
afDeviceObject.optString("persist.sys.cloud.gpu.gl_version", "")
val persist_sys_cloud_gpu_egl_vendor =
afDeviceObject.optString("persist.sys.cloud.gpu.egl_vendor", "")
val persist_sys_cloud_gpu_egl_version =
afDeviceObject.optString("persist.sys.cloud.gpu.egl_version", "")
val global_android_id = afDeviceObject.optString(".android_id", "")
val anticheck_pkgs = afDeviceObject.optString(".anticheck_pkgs", "")
val pm_list_features = afDeviceObject.optString(".pm_list_features", "")
val pm_list_libraries = afDeviceObject.optString(".pm_list_libraries", "")
val system_http_agent = afDeviceObject.optString("system.http.agent", "")
val webkit_http_agent = afDeviceObject.optString("webkit.http.agent", "")
val com_fk_tools_pkgInfo = afDeviceObject.optString(".pkg_info", "")
val appsflyerKey = afDeviceObject.optString(".appsflyerKey", "")
val appUserId = afDeviceObject.optString(".appUserId", "")
val disk = afDeviceObject.optString(".disk", "")
val operator = afDeviceObject.optString(".operator", "")
val cell_mcc = afDeviceObject.optString(".cell.mcc", "")
val cell_mnc = afDeviceObject.optString(".cell.mnc", "")
val date1 = afDeviceObject.optString(".date1", "")
val date2 = afDeviceObject.optString(".date2", "")
val bootId = afDeviceObject.optString("BootId", "")
if (time.isNotEmpty()){
timeZone = time
}
val afDevice = AfInfo()
afDevice.advertiserId = advertiserId
afDevice.model = model
afDevice.brand = brand
afDevice.androidId = androidId
afDevice.xPixels = xPixels
afDevice.yPixels = yPixels
afDevice.densityDpi = densityDpi
afDevice.country = country
afDevice.batteryLevel = batteryLevel
afDevice.stackInfo = stackInfo
afDevice.product = product
afDevice.network = network
afDevice.langCode = langCode
afDevice.cpuAbi = cpuAbi
afDevice.yDp = yDp.toLong()
TaskUtil.setAfDevice(afDevice)
val deviceInfo = DeviceInfo()
deviceInfo.lang = lang
deviceInfo.roProductBrand = ro_product_brand
deviceInfo.roProductModel = ro_product_model
deviceInfo.roProductManufacturer = ro_product_manufacturer
deviceInfo.roProductDevice = ro_product_device
deviceInfo.roProductName = ro_product_name
deviceInfo.roBuildVersionIncremental = ro_build_version_incremental
deviceInfo.roBuildFingerprint = ro_build_fingerprint
deviceInfo.roOdmBuildFingerprint = ro_odm_build_fingerprint
deviceInfo.roProductBuildFingerprint = ro_product_build_fingerprint
deviceInfo.roSystemBuildFingerprint = ro_system_build_fingerprint
deviceInfo.roSystemExtBuildFingerprint = ro_system_ext_build_fingerprint
deviceInfo.roVendorBuildFingerprint = ro_vendor_build_fingerprint
deviceInfo.roBuildPlatform = ro_build_platform
deviceInfo.persistSysCloudDrmId = persist_sys_cloud_drm_id
deviceInfo.persistSysCloudBatteryCapacity = persist_sys_cloud_battery_capacity
deviceInfo.persistSysCloudGpuGlVendor = persist_sys_cloud_gpu_gl_vendor
deviceInfo.persistSysCloudGpuGlRenderer = persist_sys_cloud_gpu_gl_renderer
deviceInfo.persistSysCloudGpuGlVersion = persist_sys_cloud_gpu_gl_version
deviceInfo.persistSysCloudGpuEglVendor = persist_sys_cloud_gpu_egl_vendor
deviceInfo.persistSysCloudGpuEglVersion = persist_sys_cloud_gpu_egl_version
TaskUtil.setDeviceInfo(deviceInfo)
jsonObject.apply {
put("modemPropertiesList", JSONArray().apply {
put(JSONObject().apply {
put("propertiesName", "MCCMNC")
put("propertiesValue", "${cell_mcc},${cell_mnc}")
})
})
put("systemPropertiesList", JSONArray().apply {
put(JSONObject().apply {
put("propertiesName", "ro.product.manufacturer")
put("propertiesValue", ro_product_manufacturer)
})
put(JSONObject().apply {
put("propertiesName", "ro.product.brand")
put("propertiesValue", ro_product_brand)
})
put(JSONObject().apply {
put("propertiesName", "ro.product.model")
put("propertiesValue", ro_product_model)
})
// put(JSONObject().apply {
// put("propertiesName", "ro.build.display.id")
// put("propertiesValue", )
// })
put(JSONObject().apply {
put("propertiesName", "ro.product.name")
put("propertiesValue", ro_product_name)
})
put(JSONObject().apply {
put("propertiesName", "ro.product.device")
put("propertiesValue", ro_product_device)
})
// put(JSONObject().apply {
// put("propertiesName", "ro.product.board")
// put("propertiesValue", bo)
// })
// put(JSONObject().apply {
// put("propertiesName", "ro.build.tags")
// put("propertiesValue", )
// })
put(JSONObject().apply {
put("propertiesName", "ro.build.fingerprint")
put("propertiesValue", ro_build_fingerprint)
})
// put(JSONObject().apply {
// put("propertiesName", "ro.build.date.utc")
// put("propertiesValue", da)
// })
// put(JSONObject().apply {
// put("propertiesName", "ro.build.user")
// put("propertiesValue", user)
// })
// put(JSONObject().apply {
// put("propertiesName", "ro.build.host")
// put("propertiesValue", device.expand.)
// })
// put(JSONObject().apply {
// put("propertiesName", "ro.build.description")
// put("propertiesValue", des)
// })
put(JSONObject().apply {
put("propertiesName", "ro.build.version.incremental")
put("propertiesValue", ro_build_version_incremental)
})
// put(JSONObject().apply {
// put("propertiesName", "ro.build.version.codename")
// put("propertiesValue", device.cod)
// })
})
put("settingPropertiesList", JSONArray().apply {
put(JSONObject().apply {
put("propertiesName", "ssaid/${recordPackageName}")
put("propertiesValue", androidId)
})
// put(JSONObject().apply {
// put("propertiesName", "bt/mac")
// put("propertiesValue", mac)
// })
put(JSONObject().apply {
put("propertiesName", "language")
put("propertiesValue", langCode)
})
put(JSONObject().apply {
put("propertiesName", "timezone")
put("propertiesValue", timeZone)
})
// put(JSONObject().apply {
// put("propertiesName", "systemvolume")
// put("propertiesValue", device.expand.)
// })
})
put("oaidPropertiesList", JSONArray().apply {
put(JSONObject().apply {
put("propertiesName", "AAID")
put("propertiesValue", advertiserId)
})
})
}
}
val jsonString = jsonObject.toString()
val response = Api.updatePad(jsonString)
val dataList = response.data
if (response.isSuccess() && dataList != null && dataList.isNotEmpty()) {
val padTask = dataList[0]
scope.launch {
Log.d("TAG", "changeDevice: $padTask")
var loop = true
while (loop) {
delay(5000)
val result = Api.padTaskDetail(padTask.taskId)
if (result == 3) {
Log.d(
"ChangeDeviceInfoUtil",
"changeDeviceInfo changeDeviceInfo success"
)
loop = false
callback.changeSuccess()
} else if (result == -1) {
Log.d("ChangeDeviceInfoUtil", "changeDeviceInfo changeDeviceInfo fail")
loop = false
callback.changeFailed()
}
}
}
}
} catch (e: JSONException) {
e.printStackTrace()
callback.changeFailed()
}
}
}

View File

@ -0,0 +1,24 @@
package com.example.studyapp.utils;
import android.util.Log;
import com.example.studyapp.MainActivity;
public class CountryCode {
public static final int DEVICE_TYPE = 2;
static final String US = "US";
static final String RU = "RU";
// 默认使用美国
static final String DEFAULT = US;
// 当前使用的国家代码
public static String currentCountry = DEFAULT;
public static String switchCountry() {
currentCountry = currentCountry.equals(US) ?
RU : US;
LogFileUtil.logAndWrite(Log.INFO, "TAG",
"Switched country to: " + currentCountry, null);
return currentCountry;
}
}

View File

@ -0,0 +1,52 @@
package com.example.studyapp.utils;
import java.io.File;
public class FileUtils {
/**
* 获取文件的父目录路径
* @param filePath 文件完整路径
* @return 父目录路径如果失败返回null
*/
public static String getParentDirectory(String filePath) {
if (filePath == null || filePath.isEmpty()) {
return null;
}
File file = new File(filePath);
File parent = file.getParentFile();
return parent != null ? parent.getAbsolutePath() : null;
}
/**
* 获取文件的父目录File对象
* @param file 文件对象
* @return 父目录File对象
*/
public static File getParentDirectory(File file) {
return file != null ? file.getParentFile() : null;
}
/**
* 获取多级上级目录
* @param file 文件对象
* @param levels 向上追溯的层级数
* @return 上级目录路径
*/
public static String getAncestorDirectory(File file, int levels) {
if (file == null || levels <= 0) {
return file != null ? file.getAbsolutePath() : null;
}
File parent = file;
for (int i = 0; i < levels; i++) {
parent = parent.getParentFile();
if (parent == null) {
break;
}
}
return parent != null ? parent.getAbsolutePath() : null;
}
}

View File

@ -2,8 +2,14 @@ package com.example.studyapp.utils;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -46,6 +52,49 @@ public class IpUtil {
} }
} }
public static String fetchGeoInfo() {
Request request = new Request.Builder()
.url("https://ipv4.geojs.io/v1/ip/geo.json")
.build();
OkHttpClient client = new OkHttpClient();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
Log.e("ClashUtil", "OkHttp request unsuccessful: " + response.code());
return null;
}
ResponseBody responseBody = response.body();
if (responseBody == null) {
Log.e("ClashUtil", "Response body is null");
return null;
}
String jsonData = responseBody.string();
Log.i("ClashUtil", "Geo info: " + jsonData);
return jsonData;
} catch (IOException e) {
Log.e("ClashUtil", "OkHttp request failed: ", e);
return null;
}
}
public static String getTimeZone(String geoInfo)
{
try {
if (!TextUtils.isEmpty(geoInfo))
{
JSONObject json = new JSONObject(geoInfo);
return json.optString("timezone", "");
}
} catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, "IpUtil", "getTimeZone: JSON error", e);
}
return "";
}
public static String checkClientIp(String excludeCountry) public static String checkClientIp(String excludeCountry)
{ {
try { try {

View File

@ -0,0 +1,64 @@
package com.example.studyapp.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipUtils {
/**
* 压缩目录为ZIP文件
* @param sourceDirPath 要压缩的目录路径/sdcard/MyFolder
* @param zipFilePath 生成的ZIP文件路径/sdcard/Archive.zip
* @throws IOException 如果操作失败
*/
public static void zipDirectory(String sourceDirPath, String zipFilePath) throws IOException {
File sourceDir = new File(sourceDirPath);
if (!sourceDir.exists() || !sourceDir.isDirectory()) {
throw new IOException("源目录不存在或不是目录");
}
try (FileOutputStream fos = new FileOutputStream(zipFilePath);
ZipOutputStream zos = new ZipOutputStream(fos)) {
addDirectoryToZip(sourceDir, sourceDir, zos);
}
}
/**
* 递归添加目录内容到ZIP
*/
private static void addDirectoryToZip(File rootDir, File currentDir, ZipOutputStream zos) throws IOException {
File[] files = currentDir.listFiles();
if (files == null) return;
for (File file : files) {
if (file.isDirectory()) {
addDirectoryToZip(rootDir, file, zos); // 递归处理子目录
} else {
addFileToZip(rootDir, file, zos);
}
}
}
/**
* 添加单个文件到ZIP
*/
private static void addFileToZip(File rootDir, File file, ZipOutputStream zos) throws IOException {
try (FileInputStream fis = new FileInputStream(file)) {
// 计算相对路径确保ZIP内目录结构正确
String relativePath = rootDir.toURI().relativize(file.toURI()).getPath();
ZipEntry zipEntry = new ZipEntry(relativePath);
zos.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
}
}
}

View File

@ -1,4 +1,8 @@
<resources> <resources>
<string name="app_name">study_app</string> <string name="app_name">study_app</string>
<string name="accessibility_service_description">This is an accessibility service.</string> <string name="accessibility_service_description">This is an accessibility service.</string>
<string name="task_executing">任务执行中</string>
<string name="button_not_found">按钮未找到</string>
<string name="network_unavailable">网络不可用</string>
<string name="stop_button_not_found">停止按钮未找到</string>
</resources> </resources>

View File

@ -1,17 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<!-- res/xml/network_security_config.xml -->
<network-security-config> <network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="true"> <domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">47.236.153.142</domain>
<domain includeSubdomains="true">8.211.204.20</domain>
<domain includeSubdomains="true">127.0.0.1</domain> <domain includeSubdomains="true">127.0.0.1</domain>
<domain includeSubdomains="true">8.217.137.25</domain>
<domain includeSubdomains="true">47.238.96.231</domain>
<domain includeSubdomains="true">192.168.30.80</domain>
</domain-config> </domain-config>
</network-security-config> </network-security-config>

View File

@ -131,14 +131,14 @@ public class TaskUtilTest {
// 运行上传方法 // 运行上传方法
String taskId = "asddasdasd"; String taskId = "asddasdasd";
TaskUtil.postDeviceInfo("b3d893cf9de3a85a", taskId, "com.example.studyapp"); //TaskUtil.postDeviceInfo("b3d893cf9de3a85a", taskId, "com.example.studyapp", ipInfo);
} }
@Test @Test
public void testGetDeviceInfoSync_Success() throws Exception { public void testGetDeviceInfoSync_Success() throws Exception {
// 运行上传方法 // 运行上传方法
TaskUtil.getDeviceInfoSync("b3d893cf9de3a85a"); //TaskUtil.getDeviceInfoSync("b3d893cf9de3a85a");
} }
// @Test // @Test

View File

@ -7,4 +7,5 @@ buildscript {
} }
plugins { plugins {
alias(libs.plugins.android.application) apply false alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
} }

288
err.log
View File

@ -1,205 +1,83 @@
2025-06-23 17:01:42.314 297-3144 ClipboardService system_server E Denying clipboard access to org.autojs.autojs6, application is not in focus nor is it a system service for user 0 ~\AndroidStudioProjects\Agent-bigo git:[Added]
2025-06-23 17:01:42.320 297-462 ClipboardService system_server E Denying clipboard access to org.autojs.autojs6, application is not in focus nor is it a system service for user 0 gradle assembleRelease
2025-06-23 17:01:42.569 297-3144 ClipboardService system_server E Denying clipboard access to org.autojs.autojs6, application is not in focus nor is it a system service for user 0
2025-06-23 17:01:43.415 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.settings/com.android.settings.SubSettings com.android.settings/com.android.settings.SubSettings Starting a Gradle Daemon (subsequent builds will be faster)
2025-06-23 17:01:44.188 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=35830, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=139, time=2, total=6066, ts=1750669303948, pr=20, ni=0, virt=1228, shr=84, s=S, cpu=0.0, mem=4.2, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=92, total=6066, ts=1750669303948, pr=20, ni=0, virt=1126, shr=38, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=259, total=6066, ts=1750669303948, pr=20, ni=0, virt=704, shr=10, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=51143, user=u0_a234, name=Script helper, pkg=com.example.studyapp, res=209, time=9, total=6066, ts=1750669303948, pr=20, ni=0, virt=14336, shr=111, s=S, cpu=36.0, mem=6.3, args=com.example.studyapp), MemEntity(id=null, pid=1532, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=307, time=374, total=6066, ts=1750669303948, pr=20, ni=0, virt=33792, shr=179, s=S, cpu=0.0, mem=9.3, args=org.autojs.autojs6), MemEntity(id=null, pid=56880, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6066, ts=1750669303948, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)] Build was configured to prefer settings repositories over project repositories but repository 'MavenLocal' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:45.397 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.settings/androidx.appcompat.app.AlertDialog com.android.settings/androidx.appcompat.app.AlertDialog Build was configured to prefer settings repositories over project repositories but repository 'MavenRepo' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:47.565 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.settings/androidx.appcompat.app.AlertDialog com.android.settings/androidx.appcompat.app.AlertDialog Build was configured to prefer settings repositories over project repositories but repository 'Google' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:51.409 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.settings/com.android.settings.SubSettings com.android.settings/com.android.settings.SubSettings Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:54.631 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.settings/com.android.settings.Settings$AccessibilitySettingsActivity com.android.settings/com.android.settings.Settings$AccessibilitySettingsActivity Build was configured to prefer settings repositories over project repositories but repository 'Alibaba' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:54.661 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.settings/com.android.settings.Settings$AccessibilitySettingsActivity com.android.settings/com.android.settings.Settings$AccessibilitySettingsActivity Build was configured to prefer settings repositories over project repositories but repository 'Bstek' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:54.733 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=35830, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=139, time=2, total=6066, ts=1750669314510, pr=20, ni=0, virt=1228, shr=84, s=S, cpu=0.0, mem=4.2, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=92, total=6066, ts=1750669314510, pr=20, ni=0, virt=1126, shr=38, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=259, total=6066, ts=1750669314510, pr=20, ni=0, virt=704, shr=10, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=51143, user=u0_a234, name=Script helper, pkg=com.example.studyapp, res=203, time=13, total=6066, ts=1750669314510, pr=20, ni=0, virt=14336, shr=111, s=S, cpu=3.8, mem=6.1, args=com.example.studyapp), MemEntity(id=null, pid=1532, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=307, time=374, total=6066, ts=1750669314510, pr=20, ni=0, virt=33792, shr=179, s=S, cpu=0.0, mem=9.3, args=org.autojs.autojs6), MemEntity(id=null, pid=56880, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6066, ts=1750669314510, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)] Build was configured to prefer settings repositories over project repositories but repository 'MavenLocal' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:56.366 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.settings/com.android.settings.Settings$AppManageExternalStorageActivity com.android.settings/com.android.settings.Settings$AppManageExternalStorageActivity Build was configured to prefer settings repositories over project repositories but repository 'MavenRepo' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:56.413 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.settings/com.android.settings.Settings$AppManageExternalStorageActivity com.android.settings/com.android.settings.Settings$AppManageExternalStorageActivity Build was configured to prefer settings repositories over project repositories but repository 'Google' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:59.870 1532-1532 NotificationObserver org.autojs.autojs6 D onNotification: [Storage Permissions granted]; EventType: TYPE_NOTIFICATION_STATE_CHANGED; EventTime: 870589469; PackageName: com.example.studyapp; MovementGranularity: 0; Action: 0; ContentChangeTypes: []; WindowChangeTypes: [] [ ClassName: android.widget.Toast; Text: [Storage Permissions granted]; ContentDescription: null; ItemCount: -1; CurrentItemIndex: -1; Enabled: false; Password: false; Checked: false; FullScreen: false; Scrollable: false; BeforeText: null; FromIndex: -1; ToIndex: -1; ScrollX: 0; ScrollY: 0; MaxScrollX: 0; MaxScrollY: 0; ScrollDeltaX: -1; ScrollDeltaY: -1; AddedCount: -1; RemovedCount: -1; ParcelableData: null ]; recordCount: 0 Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:01:59.924 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.example.studyapp/com.example.studyapp.MainActivity com.example.studyapp/com.example.studyapp.MainActivity Build was configured to prefer settings repositories over project repositories but repository 'Alibaba' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:05.235 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=35830, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=139, time=2, total=6058, ts=1750669325040, pr=20, ni=0, virt=1228, shr=84, s=S, cpu=0.0, mem=4.2, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=92, total=6058, ts=1750669325040, pr=20, ni=0, virt=1126, shr=38, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=259, total=6058, ts=1750669325040, pr=20, ni=0, virt=704, shr=10, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=51143, user=u0_a234, name=Script helper, pkg=com.example.studyapp, res=206, time=19, total=6058, ts=1750669325040, pr=10, ni=-10, virt=14336, shr=114, s=S, cpu=104.0, mem=6.2, args=com.example.studyapp), MemEntity(id=null, pid=1532, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=308, time=374, total=6058, ts=1750669325040, pr=20, ni=0, virt=33792, shr=179, s=S, cpu=0.0, mem=9.3, args=org.autojs.autojs6), MemEntity(id=null, pid=56880, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6058, ts=1750669325040, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)] Build was configured to prefer settings repositories over project repositories but repository 'Bstek' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:08.114 297-16062 ClipboardService system_server E Denying clipboard access to org.autojs.autojs6, application is not in focus nor is it a system service for user 0
2025-06-23 17:02:08.119 297-462 ClipboardService system_server E Denying clipboard access to org.autojs.autojs6, application is not in focus nor is it a system service for user 0 > Task :app:processReleaseMainManifest
2025-06-23 17:02:08.365 297-11816 ClipboardService system_server E Denying clipboard access to org.autojs.autojs6, application is not in focus nor is it a system service for user 0 C:\Users\yjj38\AndroidStudioProjects\Agent-bigo\app\src\main\AndroidManifest.xml:15:1-107 Warning:
2025-06-23 17:02:09.928 1532-1532 NotificationObserver org.autojs.autojs6 D onNotification: [任务正在执行]; EventType: TYPE_NOTIFICATION_STATE_CHANGED; EventTime: 870599525; PackageName: com.example.studyapp; MovementGranularity: 0; Action: 0; ContentChangeTypes: []; WindowChangeTypes: [] [ ClassName: android.widget.Toast; Text: [任务正在执行]; ContentDescription: null; ItemCount: -1; CurrentItemIndex: -1; Enabled: false; Password: false; Checked: false; FullScreen: false; Scrollable: false; BeforeText: null; FromIndex: -1; ToIndex: -1; ScrollX: 0; ScrollY: 0; MaxScrollX: 0; MaxScrollY: 0; ScrollDeltaX: -1; ScrollDeltaY: -1; AddedCount: -1; RemovedCount: -1; ParcelableData: null ]; recordCount: 0 Element uses-permission#android.permission.MANAGE_EXTERNAL_STORAGE at AndroidManifest.xml:15:1-107 duplicated with element declared at AndroidManifest.xml:9:1-78
2025-06-23 17:02:12.071 51143-51376 isAppInstalled com.example.studyapp D Checking if app is installed: org.autojs.autojs6
2025-06-23 17:02:12.075 51143-51376 ShellUtils com.example.studyapp D execRootCmdAndGetResult - Started execution for command: pm list packages | grep org.autojs.autojs6 > Task :app:validateSigningRelease FAILED
2025-06-23 17:02:12.120 51143-51376 ShellUtils com.example.studyapp D Shell Output: package:org.autojs.autojs6
2025-06-23 17:02:12.223 51143-51376 isAppInstalled com.example.studyapp D App is installed: org.autojs.autojs6 [Incubating] Problems report is available at: file:///C:/Users/yjj38/AndroidStudioProjects/Agent-bigo/build/reports/problems/problems-report.html
2025-06-23 17:02:12.225 297-3145 ActivityTaskManager system_server I START u0 {flg=0x10000000 cmp=org.autojs.autojs6/org.autojs.autojs.external.open.RunIntentActivity (has extras)} from uid 10234
2025-06-23 17:02:12.240 1532-1532 App org.autojs.autojs6 D setCurrentActivity: org.autojs.autojs.external.open.RunIntentActivity@aad3ba2 FAILURE: Build failed with an exception.
2025-06-23 17:02:12.243 1532-1532 ScriptEngineService org.autojs.autojs6 D JavaScriptSource: true
2025-06-23 17:02:12.246 611-2827 TelephonyPermissions com.android.phone W reportAccessDeniedToReadIdentifiers:org.autojs.autojs6:getImeiForSlot:1 * What went wrong:
2025-06-23 17:02:12.249 297-6814 TelephonyPermissions system_server W reportAccessDeniedToReadIdentifiers:org.autojs.autojs6:getSerial:-1 Execution failed for task ':app:validateSigningRelease'.
2025-06-23 17:02:12.250 1532-51468 AndroidContextFactory org.autojs.autojs6 D onContextCreated: count = 1 > Keystore file 'C:\Users\yjj38\AndroidStudioProjects\Agent-bigo\app\agent_add.jks' not found for signing config 'release'.
2025-06-23 17:02:12.250 1532-51468 ContextFactory org.autojs.autojs6 D onContextCreated: count = 1
2025-06-23 17:02:12.294 1532-51468 ScriptEngineService org.autojs.autojs6 D onStart * Try:
2025-06-23 17:02:12.299 1532-51468 GlobalConsole org.autojs.autojs6 D 09:02:12.299/V: Running [$sdcard/script/main.js]. > Run with --stacktrace option to get the stack trace.
2025-06-23 17:02:12.307 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.example.studyapp/com.example.studyapp.MainActivity com.example.studyapp/com.example.studyapp.MainActivity > Run with --info or --debug option to get more log output.
2025-06-23 17:02:12.307 1532-51469 AndroidContextFactory org.autojs.autojs6 D onContextCreated: count = 2 > Run with --scan to get full insights.
2025-06-23 17:02:12.308 1532-51470 AndroidContextFactory org.autojs.autojs6 D onContextCreated: count = 3 > Get more help at https://help.gradle.org.
2025-06-23 17:02:12.308 1532-51470 ContextFactory org.autojs.autojs6 D onContextCreated: count = 3
2025-06-23 17:02:12.308 1532-51469 ContextFactory org.autojs.autojs6 D onContextCreated: count = 2 Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
2025-06-23 17:02:12.309 1532-51471 AndroidContextFactory org.autojs.autojs6 D onContextCreated: count = 4
2025-06-23 17:02:12.309 1532-51471 ContextFactory org.autojs.autojs6 D onContextCreated: count = 4 You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
2025-06-23 17:02:12.313 1532-51469 App org.autojs.autojs6 D getCurrentActivity: org.autojs.autojs.external.open.RunIntentActivity@aad3ba2
2025-06-23 17:02:12.313 297-6814 ActivityTaskManager system_server I START u0 {flg=0x10000000 cmp=org.autojs.autojs6/org.autojs.autojs.core.activity.StartForResultActivity (has extras)} from uid 10100 For more on this, please refer to https://docs.gradle.org/8.14/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
2025-06-23 17:02:12.314 297-6814 ActivityTaskManager system_server I Launching r: ActivityRecord{a98f3cd u0 org.autojs.autojs6/org.autojs.autojs.core.activity.StartForResultActivity} from background: ActivityRecord{91ff715 u0 org.autojs.autojs6/org.autojs.autojs.external.open.RunIntentActivity} t9913 f}}. New task: true
2025-06-23 17:02:12.326 1532-1532 App org.autojs.autojs6 D setCurrentActivity: org.autojs.autojs.core.activity.StartForResultActivity@2e7ffe4 BUILD FAILED in 37s
2025-06-23 17:02:12.336 1532-1532 App org.autojs.autojs6 D setCurrentActivity: org.autojs.autojs.core.activity.StartForResultActivity@2e7ffe4 38 actionable tasks: 37 executed, 1 up-to-date
2025-06-23 17:02:12.337 1532-55975 Parcel org.autojs.autojs6 W Expecting binder but got null! ~\AndroidStudioProjects\Agent-bigo git:[Added]
2025-06-23 17:02:12.339 297-11816 CoreBackPreview system_server D Window{e9771a6 u0 org.autojs.autojs6/org.autojs.autojs.core.activity.StartForResultActivity}: Setting back callback OnBackInvokedCallbackInfo{mCallback=android.window.IOnBackInvokedCallback$Stub$Proxy@1638f94, mPriority=0} gradle assembleRelease
2025-06-23 17:02:12.340 1532-1532 App org.autojs.autojs6 D setCurrentActivity: null Build was configured to prefer settings repositories over project repositories but repository 'MavenLocal' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:12.343 1532-51478 TrafficStats org.autojs.autojs6 D tagSocket(245) with statsTag=0x4d2, statsUid=-1 Build was configured to prefer settings repositories over project repositories but repository 'MavenRepo' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:12.343 1532-51478 TrafficStats org.autojs.autojs6 I tagSocketFd(245, 1234, -1) failed with errno-9 Build was configured to prefer settings repositories over project repositories but repository 'Google' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:12.348 1532-55975 OpenGLRenderer org.autojs.autojs6 E Unable to match the desired swap behavior. Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:12.421 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.systemui/android.app.AlertDialog com.android.systemui/android.app.AlertDialog Build was configured to prefer settings repositories over project repositories but repository 'Alibaba' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:12.851 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: org.autojs.autojs6/org.autojs.autojs.core.activity.StartForResultActivity org.autojs.autojs6/org.autojs.autojs.core.activity.StartForResultActivity Build was configured to prefer settings repositories over project repositories but repository 'Bstek' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:12.871 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.android.systemui/com.android.systemui.media.MediaProjectionPermissionActivity com.android.systemui/com.android.systemui.media.MediaProjectionPermissionActivity Build was configured to prefer settings repositories over project repositories but repository 'MavenLocal' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:13.310 1532-51470 GlobalConsole org.autojs.autojs6 D 09:02:13.310/D: 计时线程: 0/600秒 Build was configured to prefer settings repositories over project repositories but repository 'MavenRepo' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:13.321 1532-1532 NotificationObserver org.autojs.autojs6 D onNotification: [计时线程: 0/600秒, AutoJs6]; EventType: TYPE_NOTIFICATION_STATE_CHANGED; EventTime: 870602921; PackageName: org.autojs.autojs6; MovementGranularity: 0; Action: 0; ContentChangeTypes: []; WindowChangeTypes: [] [ ClassName: android.widget.Toast; Text: [计时线程: 0/600秒, AutoJs6]; ContentDescription: null; ItemCount: -1; CurrentItemIndex: -1; Enabled: false; Password: false; Checked: false; FullScreen: false; Scrollable: false; BeforeText: null; FromIndex: -1; ToIndex: -1; ScrollX: 0; ScrollY: 0; MaxScrollX: 0; MaxScrollY: 0; ScrollDeltaX: -1; ScrollDeltaY: -1; AddedCount: -1; RemovedCount: -1; ParcelableData: null ]; recordCount: 0 Build was configured to prefer settings repositories over project repositories but repository 'Google' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:13.827 1532-51471 GlobalConsole org.autojs.autojs6 D 09:02:13.827/D: 点击START NOW Build was configured to prefer settings repositories over project repositories but repository 'maven' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:13.828 1532-51471 GlobalActionAutomator org.autojs.autojs6 D Path moved to (889.0, 1173.0) Build was configured to prefer settings repositories over project repositories but repository 'Alibaba' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:13.829 1532-51471 GlobalActionAutomator org.autojs.autojs6 D dispatchGesture: true Build was configured to prefer settings repositories over project repositories but repository 'Bstek' was added by initialization script 'C:\Program Files\gradle-8.14\init.d\init.gradle'
2025-06-23 17:02:14.058 297-3144 DisplayDeviceRepository system_server I Display device added: DisplayDeviceInfo{"ScreenCapturer": uniqueId="virtual:org.autojs.autojs6,10100,ScreenCapturer,0", 1080 x 1920, modeId 14, defaultModeId 14, supportedModes [{id=14, width=1080, height=1920, fps=60.0, alternativeRefreshRates=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 16666666, touch NONE, rotation 0, type VIRTUAL, deviceProductInfo null, state ON, committedState UNKNOWN, owner org.autojs.autojs6 (uid 10100), frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, FLAG_PRIVATE, FLAG_PRESENTATION, installOrientation 0} > Task :app:validateSigningRelease FAILED
2025-06-23 17:02:14.062 297-3144 LogicalDisplayMapper system_server I Adding new display: 14: DisplayInfo{"ScreenCapturer", displayId 14", displayGroupId -1, FLAG_PRIVATE, FLAG_PRESENTATION, real 1080 x 1920, largest app 1080 x 1920, smallest app 1080 x 1920, appVsyncOff 0, presDeadline 16666666, mode 14, defaultMode 14, modes [{id=14, width=1080, height=1920, fps=60.0, alternativeRefreshRates=[]}], hdrCapabilities null, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state ON, committedState UNKNOWN, type VIRTUAL, uniqueId "virtual:org.autojs.autojs6,10100,ScreenCapturer,0", app 1080 x 1920, density 320 (320.0 x 320.0) dpi, layerStack 14, colorMode 0, supportedColorModes [0], deviceProductInfo null, owner org.autojs.autojs6 (uid 10100), removeMode 1, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, installOrientation ROTATION_0}
2025-06-23 17:02:14.070 297-313 DisplayManagerService system_server W Display DisplayDeviceInfo{"ScreenCapturer": uniqueId="virtual:org.autojs.autojs6,10100,ScreenCapturer,0", 1080 x 1920, modeId 14, defaultModeId 14, supportedModes [{id=14, width=1080, height=1920, fps=60.0, alternativeRefreshRates=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 16666666, touch NONE, rotation 0, type VIRTUAL, deviceProductInfo null, state ON, committedState UNKNOWN, owner org.autojs.autojs6 (uid 10100), frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, FLAG_PRIVATE, FLAG_PRESENTATION, installOrientation 0} does not support input device matching. [Incubating] Problems report is available at: file:///C:/Users/yjj38/AndroidStudioProjects/Agent-bigo/build/reports/problems/problems-report.html
2025-06-23 17:02:14.071 297-313 DisplayManagerService system_server W Display DisplayDeviceInfo{"ScreenCapturer": uniqueId="virtual:org.autojs.autojs6,10100,ScreenCapturer,0", 1080 x 1920, modeId 14, defaultModeId 14, supportedModes [{id=14, width=1080, height=1920, fps=60.0, alternativeRefreshRates=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 16666666, touch NONE, rotation 0, type VIRTUAL, deviceProductInfo null, state ON, committedState UNKNOWN, owner org.autojs.autojs6 (uid 10100), frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, FLAG_PRIVATE, FLAG_PRESENTATION, installOrientation 0} does not support input device matching.
2025-06-23 17:02:14.072 297-313 DisplayDevice system_server I [14] Layerstack set to 14 for virtual:org.autojs.autojs6,10100,ScreenCapturer,0 FAILURE: Build failed with an exception.
2025-06-23 17:02:14.073 297-313 DisplayManagerService system_server W Display DisplayDeviceInfo{"ScreenCapturer": uniqueId="virtual:org.autojs.autojs6,10100,ScreenCapturer,0", 1080 x 1920, modeId 14, defaultModeId 14, supportedModes [{id=14, width=1080, height=1920, fps=60.0, alternativeRefreshRates=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 16666666, touch NONE, rotation 0, type VIRTUAL, deviceProductInfo null, state ON, committedState UNKNOWN, owner org.autojs.autojs6 (uid 10100), frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, FLAG_PRIVATE, FLAG_PRESENTATION, installOrientation 0} does not support input device matching.
2025-06-23 17:02:14.075 1532-1532 AndroidContextFactory org.autojs.autojs6 D onContextCreated: count = 5 * What went wrong:
2025-06-23 17:02:14.075 1532-1532 ContextFactory org.autojs.autojs6 D onContextCreated: count = 5 Execution failed for task ':app:validateSigningRelease'.
2025-06-23 17:02:14.076 1532-1532 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 4 > Keystore file 'C:\Users\yjj38\AndroidStudioProjects\Agent-bigo\app\agent_add.jks' not found for signing config 'release'.
2025-06-23 17:02:14.076 1532-1532 ContextFactory org.autojs.autojs6 D onContextReleased: count = 4
2025-06-23 17:02:14.078 297-316 DisplayManagerService system_server W Display DisplayDeviceInfo{"ScreenCapturer": uniqueId="virtual:org.autojs.autojs6,10100,ScreenCapturer,0", 1080 x 1920, modeId 14, defaultModeId 14, supportedModes [{id=14, width=1080, height=1920, fps=60.0, alternativeRefreshRates=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 16666666, touch NONE, rotation 0, type VIRTUAL, deviceProductInfo null, state ON, committedState UNKNOWN, owner org.autojs.autojs6 (uid 10100), frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, FLAG_PRIVATE, FLAG_PRESENTATION, installOrientation 0} does not support input device matching. * Try:
2025-06-23 17:02:14.079 297-334 DisplayPow...roller[14] system_server I BrightnessEvent: disp=14, physDisp=virtual:org.autojs.autojs6,10100,ScreenCapturer,0, brt=0.035433073, initBrt=NaN, rcmdBrt=NaN, preBrt=NaN, lux=0.0, preLux=0.0, hbmMax=1.0, hbmMode=off, rbcStrength=-1, powerFactor=1.0, thrmMax=1.0, wasShortTermModelActive=false, flags=, reason=manual, autoBrightness=false > Run with --stacktrace option to get the stack trace.
2025-06-23 17:02:14.079 297-334 DisplayPow...roller[14] system_server I BrightnessEvent: disp=14, physDisp=virtual:org.autojs.autojs6,10100,ScreenCapturer,0, brt=0.035433073, initBrt=0.035433073, rcmdBrt=NaN, preBrt=NaN, lux=0.0, preLux=0.0, hbmMax=1.0, hbmMode=off, rbcStrength=-1, powerFactor=1.0, thrmMax=1.0, wasShortTermModelActive=false, flags=, reason=manual, autoBrightness=false > Run with --info or --debug option to get more log output.
2025-06-23 17:02:14.079 297-334 DisplayPow...roller[14] system_server I BrightnessEvent: disp=14, physDisp=virtual:org.autojs.autojs6,10100,ScreenCapturer,0, brt=0.035433073, initBrt=0.035433073, rcmdBrt=NaN, preBrt=NaN, lux=0.0, preLux=0.0, hbmMax=1.0, hbmMode=off, rbcStrength=-1, powerFactor=1.0, thrmMax=1.0, wasShortTermModelActive=false, flags=, reason=manual, autoBrightness=false > Run with --scan to get full insights.
2025-06-23 17:02:14.079 297-334 DisplayPow...roller[14] system_server I BrightnessEvent: disp=14, physDisp=virtual:org.autojs.autojs6,10100,ScreenCapturer,0, brt=0.035433073, initBrt=0.035433073, rcmdBrt=NaN, preBrt=NaN, lux=0.0, preLux=0.0, hbmMax=1.0, hbmMode=off, rbcStrength=-1, powerFactor=1.0, thrmMax=1.0, wasShortTermModelActive=false, flags=, reason=manual, autoBrightness=false > Get more help at https://help.gradle.org.
2025-06-23 17:02:14.079 297-334 DisplayPow...roller[14] system_server I BrightnessEvent: disp=14, physDisp=virtual:org.autojs.autojs6,10100,ScreenCapturer,0, brt=0.035433073, initBrt=0.035433073, rcmdBrt=NaN, preBrt=NaN, lux=0.0, preLux=0.0, hbmMax=1.0, hbmMode=off, rbcStrength=-1, powerFactor=1.0, thrmMax=1.0, wasShortTermModelActive=false, flags=, reason=manual, autoBrightness=false
2025-06-23 17:02:14.080 297-3144 ActivityTaskManager system_server W Duplicate finish request for r=ActivityRecord{a98f3cd u0 org.autojs.autojs6/org.autojs.autojs.core.activity.StartForResultActivity} t9914 f}} Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
2025-06-23 17:02:14.081 1532-1532 AndroidContextFactory org.autojs.autojs6 D onContextCreated: count = 5
2025-06-23 17:02:14.081 1532-1532 ContextFactory org.autojs.autojs6 D onContextCreated: count = 5 You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
2025-06-23 17:02:14.081 1532-1532 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 4
2025-06-23 17:02:14.081 1532-1532 ContextFactory org.autojs.autojs6 D onContextReleased: count = 4 For more on this, please refer to https://docs.gradle.org/8.14/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
2025-06-23 17:02:14.082 1532-1532 AndroidContextFactory org.autojs.autojs6 D onContextCreated: count = 5
2025-06-23 17:02:14.082 1532-1532 ContextFactory org.autojs.autojs6 D onContextCreated: count = 5 BUILD FAILED in 6s
2025-06-23 17:02:14.082 1532-1532 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 4 39 actionable tasks: 10 executed, 29 up-to-date
2025-06-23 17:02:14.082 1532-1532 ContextFactory org.autojs.autojs6 D onContextReleased: count = 4
2025-06-23 17:02:14.083 1532-51469 GlobalConsole org.autojs.autojs6 D 09:02:14.082/D: 首次 Threds errorFailed to invoke method app.viewFile. Cannot view /sdcard/script/launcher-release.apk as it doesn't exist (/storage/emulated/0/script/main.js#647)
2025-06-23 17:02:14.083 1532-51469 GlobalConsole org.autojs.autojs6 D 09:02:14.083/D: 首次 脚本线程 脚本catch结束
2025-06-23 17:02:14.084 1532-51470 System.err org.autojs.autojs6 W org.mozilla.javascript.WrappedException: Wrapped org.autojs.autojs.runtime.exception.ScriptInterruptedException (/storage/emulated/0/script/main.js#105)
2025-06-23 17:02:14.084 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.Augmentable.augmentFunctionsBy$lambda$24$lambda$23(Augmentable.kt:432)
2025-06-23 17:02:14.084 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.Augmentable.$r8$lambda$Fn1T-F1qaCuaZ27e1ntAmyEtA5M(Unknown Source:0)
2025-06-23 17:02:14.084 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.Augmentable$$ExternalSyntheticLambda3.invoke(D8$$SyntheticClass:0)
2025-06-23 17:02:14.084 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils$InternalBaseFunction.callFunc$app_appRelease(RhinoUtils.kt:877)
2025-06-23 17:02:14.084 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils$newBaseFunction$5.call(RhinoUtils.kt:237)
2025-06-23 17:02:14.084 1532-51470 System.err org.autojs.autojs6 W at org.mozilla.javascript.Interpreter.doCallByteCode(Interpreter.java:3019)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:1973)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at script(/storage/emulated/0/script/main.js:105)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:1161)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:87)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:347)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:4450)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.callFunction$lambda$7(RhinoUtils.kt:169)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.$r8$lambda$f8ShGIQnCN3BfY5ui2ZDzafysTo(Unknown Source:0)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils$$ExternalSyntheticLambda3.invoke(D8$$SyntheticClass:0)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.withRhinoContext(RhinoUtils.kt:754)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.callFunction(RhinoUtils.kt:164)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.callFunction(RhinoUtils.kt:153)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.callFunction(RhinoUtils.kt:141)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.coerceRunnable$lambda$26(RhinoUtils.kt:435)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.$r8$lambda$spHwZG5wVYypfhMmC-EzLoJxvzU(Unknown Source:0)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils$$ExternalSyntheticLambda1.run(D8$$SyntheticClass:0)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at android.os.Handler.handleCallback(Handler.java:942)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at android.os.Handler.dispatchMessage(Handler.java:99)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at android.os.Looper.loopOnce(Looper.java:201)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at android.os.Looper.loop(Looper.java:288)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.core.looper.TimerThread.run(TimerThread.kt:56)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W Caused by: org.autojs.autojs.runtime.exception.ScriptInterruptedException
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.ScriptRuntime.sleep(ScriptRuntime.kt:507)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global$Companion.sleep$lambda$20(Global.kt:244)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global$Companion.$r8$lambda$OWAsxQgJG0C1vfHeAuhT_906-VY(Unknown Source:0)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global$Companion$$ExternalSyntheticLambda19.invoke(D8$$SyntheticClass:0)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.extension.FlexibleArray$Companion.unwrapAndInvokeAll(FlexibleArray.kt:76)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.extension.FlexibleArray$Companion.ensureArgumentsLengthInRange(FlexibleArray.kt:56)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global$Companion.sleep(Global.kt:224)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global.sleep(Unknown Source:2)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at java.lang.reflect.Method.invoke(Native Method)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.Augmentable.augmentFunctionsBy$lambda$24$lambda$23(Augmentable.kt:415)
2025-06-23 17:02:14.085 1532-51470 System.err org.autojs.autojs6 W ... 25 more
2025-06-23 17:02:14.085 1532-51470 Loopers org.autojs.autojs6 D notifyThreadExit: Thread[ScriptThread-8[/storage/emulated/0/script/main.js] (Spawn-1),5]
2025-06-23 17:02:14.085 1532-51470 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 3
2025-06-23 17:02:14.085 1532-51470 ContextFactory org.autojs.autojs6 D onContextReleased: count = 3
2025-06-23 17:02:14.085 1532-51469 Loopers org.autojs.autojs6 D notifyThreadExit: Thread[ScriptThread-8[/storage/emulated/0/script/main.js] (Spawn-0),5]
2025-06-23 17:02:14.085 1532-51469 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 2
2025-06-23 17:02:14.085 1532-51469 ContextFactory org.autojs.autojs6 D onContextReleased: count = 2
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W org.mozilla.javascript.WrappedException: Wrapped org.autojs.autojs.runtime.exception.ScriptInterruptedException (/storage/emulated/0/script/main.js#160)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.Augmentable.augmentFunctionsBy$lambda$24$lambda$23(Augmentable.kt:432)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.Augmentable.$r8$lambda$Fn1T-F1qaCuaZ27e1ntAmyEtA5M(Unknown Source:0)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.Augmentable$$ExternalSyntheticLambda3.invoke(D8$$SyntheticClass:0)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils$InternalBaseFunction.callFunc$app_appRelease(RhinoUtils.kt:877)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils$newBaseFunction$5.call(RhinoUtils.kt:237)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.mozilla.javascript.Interpreter.doCallByteCode(Interpreter.java:3019)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:1973)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at script(/storage/emulated/0/script/main.js:160)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:1161)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:87)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:347)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:4450)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.callFunction$lambda$7(RhinoUtils.kt:169)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.$r8$lambda$f8ShGIQnCN3BfY5ui2ZDzafysTo(Unknown Source:0)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils$$ExternalSyntheticLambda3.invoke(D8$$SyntheticClass:0)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.withRhinoContext(RhinoUtils.kt:754)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.callFunction(RhinoUtils.kt:164)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.callFunction(RhinoUtils.kt:153)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.callFunction(RhinoUtils.kt:141)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.coerceRunnable$lambda$26(RhinoUtils.kt:435)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils.$r8$lambda$spHwZG5wVYypfhMmC-EzLoJxvzU(Unknown Source:0)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.util.RhinoUtils$$ExternalSyntheticLambda1.run(D8$$SyntheticClass:0)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at android.os.Handler.handleCallback(Handler.java:942)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at android.os.Handler.dispatchMessage(Handler.java:99)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at android.os.Looper.loopOnce(Looper.java:201)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at android.os.Looper.loop(Looper.java:288)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.core.looper.TimerThread.run(TimerThread.kt:56)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W Caused by: org.autojs.autojs.runtime.exception.ScriptInterruptedException
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.ScriptRuntime.sleep(ScriptRuntime.kt:507)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global$Companion.sleep$lambda$20(Global.kt:244)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global$Companion.$r8$lambda$OWAsxQgJG0C1vfHeAuhT_906-VY(Unknown Source:0)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global$Companion$$ExternalSyntheticLambda19.invoke(D8$$SyntheticClass:0)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.extension.FlexibleArray$Companion.unwrapAndInvokeAll(FlexibleArray.kt:76)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.extension.FlexibleArray$Companion.ensureArgumentsLengthInRange(FlexibleArray.kt:56)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global$Companion.sleep(Global.kt:224)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.global.Global.sleep(Unknown Source:2)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at java.lang.reflect.Method.invoke(Native Method)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W at org.autojs.autojs.runtime.api.augment.Augmentable.augmentFunctionsBy$lambda$24$lambda$23(Augmentable.kt:415)
2025-06-23 17:02:14.086 1532-51471 System.err org.autojs.autojs6 W ... 25 more
2025-06-23 17:02:14.086 1532-51471 Loopers org.autojs.autojs6 D notifyThreadExit: Thread[ScriptThread-8[/storage/emulated/0/script/main.js] (Spawn-2),5]
2025-06-23 17:02:14.086 1532-51471 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 1
2025-06-23 17:02:14.086 1532-51471 ContextFactory org.autojs.autojs6 D onContextReleased: count = 1
2025-06-23 17:02:14.087 1532-51468 GlobalConsole org.autojs.autojs6 D 09:02:14.087/V: [$sdcard/script/main.js] finished in 1.787 seconds.
2025-06-23 17:02:14.087 1532-51468 RunnableJSExecution org.autojs.autojs6 D Engine destroy
2025-06-23 17:02:14.087 1532-51468 ScriptRuntime org.autojs.autojs6 D on exit
2025-06-23 17:02:14.087 1532-51468 Loopers org.autojs.autojs6 D recycle
2025-06-23 17:02:14.089 297-3143 DisplayDeviceRepository system_server I Display device removed: DisplayDeviceInfo{"ScreenCapturer": uniqueId="virtual:org.autojs.autojs6,10100,ScreenCapturer,0", 1080 x 1920, modeId 14, defaultModeId 14, supportedModes [{id=14, width=1080, height=1920, fps=60.0, alternativeRefreshRates=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 16666666, touch NONE, rotation 0, type VIRTUAL, deviceProductInfo null, state ON, committedState UNKNOWN, owner org.autojs.autojs6 (uid 10100), frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, FLAG_PRIVATE, FLAG_PRESENTATION, installOrientation 0}
2025-06-23 17:02:14.093 1532-51468 RhinoJavaScriptEngine org.autojs.autojs6 D on destroy
2025-06-23 17:02:14.093 1532-51468 AndroidContextFactory org.autojs.autojs6 D onContextReleased: count = 0
2025-06-23 17:02:14.093 1532-51468 ContextFactory org.autojs.autojs6 D onContextReleased: count = 0
2025-06-23 17:02:14.093 1532-5003 BufferQueueProducer org.autojs.autojs6 E [ImageReader-1080x1920f1m3-1532-8](id:5fc00000021,api:1,p:52,c:1532) dequeueBuffer: BufferQueue has been abandoned
2025-06-23 17:02:14.099 1532-1532 ActivityInfoProvider org.autojs.autojs6 D setLatestComponent: com.example.studyapp/com.example.studyapp.MainActivity com.example.studyapp/com.example.studyapp.MainActivity
2025-06-23 17:02:14.102 1532-5003 BpBinder org.autojs.autojs6 I onLastStrongRef automatically unlinking death recipients: <uncached descriptor>
2025-06-23 17:02:14.103 297-6815 CoreBackPreview system_server D Window{e9771a6 u0 org.autojs.autojs6/org.autojs.autojs.core.activity.StartForResultActivity}: Setting back callback null
2025-06-23 17:02:14.104 297-6815 InputManager-JNI system_server W Input channel object 'e9771a6 org.autojs.autojs6/org.autojs.autojs.core.activity.StartForResultActivity (client)' was disposed without first being removed with the input manager!
2025-06-23 17:02:14.251 297-297 NotificationService system_server I Cannot find enqueued record for key: 0|org.autojs.autojs6|207|null|10100
2025-06-23 17:02:15.923 297-3145 NotificationService system_server W Toast already killed. pkg=org.autojs.autojs6 token=android.os.BinderProxy@fb6cbea
2025-06-23 17:02:15.934 1532-1532 NotificationObserver org.autojs.autojs6 D onNotification: [首次 Threds errorFailed to invoke method app.viewFile. Cannot view /sdcard/script/launcher-release.apk as it doesn't exist (/storage/emulated/0/script/main.js#647), AutoJs6]; EventType: TYPE_NOTIFICATION_STATE_CHANGED; EventTime: 870605533; PackageName: org.autojs.autojs6; MovementGranularity: 0; Action: 0; ContentChangeTypes: []; WindowChangeTypes: [] [ ClassName: android.widget.Toast; Text: [首次 Threds errorFailed to invoke method app.viewFile. Cannot view /sdcard/script/launcher-release.apk as it doesn't exist (/storage/emulated/0/script/main.js#647), AutoJs6]; ContentDescription: null; ItemCount: -1; CurrentItemIndex: -1; Enabled: false; Password: false; Checked: false; FullScreen: false; Scrollable: false; BeforeText: null; FromIndex: -1; ToIndex: -1; ScrollX: 0; ScrollY: 0; MaxScrollX: 0; MaxScrollY: 0; ScrollDeltaX: -1; ScrollDeltaY: -1; AddedCount: -1; RemovedCount: -1; ParcelableData: null ]; recordCount: 0
2025-06-23 17:02:16.164 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=35830, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=139, time=2, total=5956, ts=1750669335563, pr=20, ni=0, virt=1228, shr=84, s=S, cpu=0.0, mem=4.2, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=92, total=5956, ts=1750669335563, pr=20, ni=0, virt=1126, shr=38, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=259, total=5956, ts=1750669335563, pr=20, ni=0, virt=704, shr=10, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=51143, user=u0_a234, name=Script helper, pkg=com.example.studyapp, res=212, time=22, total=5956, ts=1750669335563, pr=10, ni=-10, virt=14336, shr=115, s=S, cpu=0.0, mem=6.4, args=com.example.studyapp), MemEntity(id=null, pid=1532, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=314, time=374, total=5956, ts=1750669335563, pr=20, ni=0, virt=33792, shr=179, s=S, cpu=0.0, mem=9.5, args=org.autojs.autojs6), MemEntity(id=null, pid=56880, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=5956, ts=1750669335563, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-23 17:02:18.505 297-3143 NotificationService system_server W Toast already killed. pkg=org.autojs.autojs6 token=android.os.BinderProxy@c258390
2025-06-23 17:02:18.517 1532-1532 NotificationObserver org.autojs.autojs6 D onNotification: [首次 脚本线程 脚本catch结束, AutoJs6]; EventType: TYPE_NOTIFICATION_STATE_CHANGED; EventTime: 870608116; PackageName: org.autojs.autojs6; MovementGranularity: 0; Action: 0; ContentChangeTypes: []; WindowChangeTypes: [] [ ClassName: android.widget.Toast; Text: [首次 脚本线程 脚本catch结束, AutoJs6]; ContentDescription: null; ItemCount: -1; CurrentItemIndex: -1; Enabled: false; Password: false; Checked: false; FullScreen: false; Scrollable: false; BeforeText: null; FromIndex: -1; ToIndex: -1; ScrollX: 0; ScrollY: 0; MaxScrollX: 0; MaxScrollY: 0; ScrollDeltaX: -1; ScrollDeltaY: -1; AddedCount: -1; RemovedCount: -1; ParcelableData: null ]; recordCount: 0
2025-06-23 17:02:21.098 297-3143 NotificationService system_server W Toast already killed. pkg=org.autojs.autojs6 token=android.os.BinderProxy@afcbf66
2025-06-23 17:02:23.095 1532-51478 TrafficStats org.autojs.autojs6 D tagSocket(92) with statsTag=0x4d2, statsUid=-1
2025-06-23 17:02:23.095 1532-51478 TrafficStats org.autojs.autojs6 I tagSocketFd(92, 1234, -1) failed with errno-9
2025-06-23 17:02:24.589 1532-51478 TrafficStats org.autojs.autojs6 D tagSocket(92) with statsTag=0x4d2, statsUid=-1
2025-06-23 17:02:24.589 1532-51478 TrafficStats org.autojs.autojs6 I tagSocketFd(92, 1234, -1) failed with errno-9
2025-06-23 17:02:26.771 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=35830, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=139, time=2, total=6027, ts=1750669346510, pr=20, ni=0, virt=1228, shr=84, s=S, cpu=0.0, mem=4.2, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=92, total=6027, ts=1750669346510, pr=20, ni=0, virt=1126, shr=38, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=259, total=6027, ts=1750669346510, pr=20, ni=0, virt=704, shr=10, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=51143, user=u0_a234, name=Script helper, pkg=com.example.studyapp, res=212, time=22, total=6027, ts=1750669346510, pr=10, ni=-10, virt=14336, shr=115, s=S, cpu=0.0, mem=6.4, args=com.example.studyapp), MemEntity(id=null, pid=1532, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=315, time=374, total=6027, ts=1750669346510, pr=20, ni=0, virt=33792, shr=179, s=S, cpu=0.0, mem=9.6, args=org.autojs.autojs6), MemEntity(id=null, pid=56880, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6027, ts=1750669346510, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]
2025-06-23 17:02:35.613 1532-51478 TrafficStats org.autojs.autojs6 D tagSocket(92) with statsTag=0x4d2, statsUid=-1
2025-06-23 17:02:35.613 1532-51478 TrafficStats org.autojs.autojs6 I tagSocketFd(92, 1234, -1) failed with errno-9
2025-06-23 17:02:36.534 1532-51478 TrafficStats org.autojs.autojs6 D tagSocket(92) with statsTag=0x4d2, statsUid=-1
2025-06-23 17:02:36.535 1532-51478 TrafficStats org.autojs.autojs6 I tagSocketFd(92, 1234, -1) failed with errno-9
2025-06-23 17:02:37.413 2002-2092 MemInfoService com.android.expansiontools D memScan: [MemEntity(id=null, pid=35830, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=139, time=2, total=6034, ts=1750669357102, pr=20, ni=0, virt=1228, shr=84, s=S, cpu=0.0, mem=4.2, args=com.github.kr328.clash), MemEntity(id=null, pid=63204, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=123, time=92, total=6034, ts=1750669357102, pr=20, ni=0, virt=1126, shr=38, s=S, cpu=0.0, mem=3.7, args=com.github.kr328.clash:core), MemEntity(id=null, pid=63228, user=u0_a104, name=Clash for Android, pkg=com.github.kr328.clash, res=25, time=259, total=6034, ts=1750669357102, pr=20, ni=0, virt=704, shr=10, s=S, cpu=0.0, mem=0.7, args=libclash.so), MemEntity(id=null, pid=51143, user=u0_a234, name=Script helper, pkg=com.example.studyapp, res=212, time=22, total=6034, ts=1750669357102, pr=10, ni=-10, virt=14336, shr=115, s=S, cpu=0.0, mem=6.4, args=com.example.studyapp), MemEntity(id=null, pid=1532, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=315, time=374, total=6034, ts=1750669357102, pr=20, ni=0, virt=33792, shr=179, s=S, cpu=0.0, mem=9.6, args=org.autojs.autojs6), MemEntity(id=null, pid=56880, user=u0_a100, name=AutoJs6, pkg=org.autojs.autojs6, res=0, time=0, total=6034, ts=1750669357102, pr=20, ni=0, virt=10240, shr=0, s=S, cpu=0.0, mem=0.0, args=sh)]

View File

@ -8,6 +8,8 @@ material = "1.12.0"
activity = "1.10.1" activity = "1.10.1"
constraintlayout = "2.2.1" constraintlayout = "2.2.1"
playServicesAdsIdentifier = "18.2.0" playServicesAdsIdentifier = "18.2.0"
kotlin = "2.0.21"
coreKtx = "1.16.0"
[libraries] [libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" } junit = { group = "junit", name = "junit", version.ref = "junit" }
@ -18,6 +20,8 @@ material = { group = "com.google.android.material", name = "material", version.r
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
play-services-ads-identifier = { group = "com.google.android.gms", name = "play-services-ads-identifier", version.ref = "playServicesAdsIdentifier" } play-services-ads-identifier = { group = "com.google.android.gms", name = "play-services-ads-identifier", version.ref = "playServicesAdsIdentifier" }
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

164
main.js
View File

@ -1,13 +1,155 @@
var message = "任务已启动"; // ========== 日志写入文件的封装 ==========
function log(...args) {
function sendMessage(message) { const message = `[LOG] ${args.map(a =>
app.sendBroadcast({ typeof a === 'object' ? JSON.stringify(a) : a
action: "org.autojs.SCRIPT_FINISHED", // 自定义广播 Action ).join(' ')}`;
extras: { console.log(message);
result: message, files.append("/sdcard/output_log.txt", new Date().toISOString() + " " + message + "\n");
package: "org.autojs.autojs6"// 将结果附加到广播中
}
});
} }
sendMessage(message + "点击开始") function error(...args) {
const message = `[ERROR] ${args.map(a =>
typeof a === 'object' ? JSON.stringify(a) : a
).join(' ')}`;
console.error(message);
files.append("/sdcard/output_log.txt", new Date().toISOString() + " " + message + "\n");
}
// ========== 网络请求封装 ==========
function httpGetWithCallbacks(url, successCallback, errorCallback) {
http.get(url, {}, (res, err) => {
if (err) {
if (errorCallback) errorCallback(err);
} else {
if (successCallback) successCallback(res);
}
});
}
function processIpApiWithCallbacks(url, processSuccessCallback, errorMsgPrefix, apiDoneCallback) {
httpGetWithCallbacks(url,
(res) => {
let operationSuccessful = false;
if (!res) {
toast(errorMsgPrefix + "请求没有返回有效响应");
log(errorMsgPrefix + "请求没有返回有效响应");
if (apiDoneCallback) apiDoneCallback(new Error("No valid response from request (res is null)"));
return;
}
if (res.statusCode != 200) {
let errorBody = "";
try {
if (res.body && typeof res.body.string === 'function') {
errorBody = res.body.string(); // 读取并关闭
}
} catch (e) {
error(errorMsgPrefix + "读取错误响应体失败: ", e);
}
toast(errorMsgPrefix + "获取失败,状态码: " + res.statusCode);
log(errorMsgPrefix + "获取失败,状态码: " + res.statusCode + ", Body: " + errorBody);
if (apiDoneCallback) apiDoneCallback(new Error(errorMsgPrefix + "获取失败,状态码: " + res.statusCode));
return;
}
try {
let data = res.body.json(); // 读取并关闭
processSuccessCallback(data);
operationSuccessful = true;
} catch (jsonError) {
toast(errorMsgPrefix + "解析JSON失败");
error(errorMsgPrefix + "解析JSON失败: ", jsonError);
if (apiDoneCallback) apiDoneCallback(jsonError);
return;
}
if (apiDoneCallback) apiDoneCallback(null);
},
(requestError) => {
error(errorMsgPrefix + "处理时发生错误: ", requestError);
if (!toast.isShow()) {
toast(errorMsgPrefix + "请求或处理失败");
}
if (apiDoneCallback) apiDoneCallback(requestError);
}
);
}
// ========== 主函数 ==========
function main() {
log("Main function started.");
let tasksCompleted = 0;
const totalTasks = 2;
let errors = [];
function checkAllTasksDone() {
tasksCompleted++;
if (tasksCompleted === totalTasks) {
log("All API calls have finished processing.");
if (errors.length > 0) {
error("One or more API calls failed:");
errors.forEach(err => error(err));
toast("部分API请求失败请检查日志");
} else {
log("All API calls were successful.");
toast("所有API请求成功");
}
log("Script operations concluded. Adding a small delay for UI.");
sleep(500);
}
}
function handleApiError(error) {
if (error) {
errors.push(error);
}
checkAllTasksDone();
}
// 调用第一个 API
processIpApiWithCallbacks(
"https://ipv4.geojs.io/v1/ip/country.json",
function(data2) {
toast("国家代码: " + data2.country);
log("地理位置信息:");
log("国家代码 (2位): " + data2.country);
log("国家代码 (3位): " + data2.country_3);
log("IP 地址: " + data2.ip);
log("国家名称: " + data2.name);
},
"地理位置",
handleApiError
);
// 调用第二个 API
processIpApiWithCallbacks(
"https://ipv4.geojs.io/v1/ip/geo.json",
function(data3) {
log("新增接口返回的地理数据:");
log("经度: " + data3.longitude);
log("纬度: " + data3.latitude);
log("城市: " + data3.city);
log("地区: " + data3.region);
log("国家: " + data3.country);
log("组织名称: " + data3.organization_name);
log("IP 地址: " + data3.ip);
log("国家代码 (2位): " + data3.country_code);
log("国家代码 (3位): " + data3.country_code3);
log("时区: " + data3.timezone);
log("ASN: " + data3.asn);
log("洲: " + data3.continent_code);
},
"详细地理位置",
handleApiError
);
}
// ========== 启动主函数并设置定时器 ==========
(function startLoop() {
const intervalMillis = 60 * 1000; // 每隔 60 秒执行一次
main(); // 首次启动
setInterval(main, intervalMillis); // 循环执行
})();

Binary file not shown.

Binary file not shown.