Add AutoRobot directory with Windows line endings

This commit is contained in:
2025-10-20 09:04:09 +08:00
parent a7ade87dde
commit d663118a73
124 changed files with 22719 additions and 0 deletions

15
AutoRobot/Android/Robot/.gitignore vendored Normal file
View File

@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

1
AutoRobot/Android/Robot/.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
AutoBot

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CopilotChatHistory">
<option name="conversations">
<list>
<Conversation>
<option name="createTime" value="1756284751508" />
<option name="id" value="0198eaba8e947ac69dd638ab8aae0f3d" />
<option name="title" value="新对话 2025年8月27日 16:52:31" />
<option name="updateTime" value="1756284751508" />
</Conversation>
</list>
</option>
</component>
</project>

View File

@@ -0,0 +1,123 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<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>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

View File

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

View File

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

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-08-28T03:49:34.091563600Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=uktceuguxoylem69" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
</project>

20
AutoRobot/Android/Robot/.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="D:\Android\.gradle\wrapper\dists\gradle-8.13-bin\5powy3u4a3a1gfbu0tco4as7a\gradle-8.13" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

9
AutoRobot/Android/Robot/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<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" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>

6
AutoRobot/Android/Robot/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -0,0 +1,45 @@
kotlin version: 2.0.21
error message: Failed connecting to the daemon in 4 retries
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:76)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:210)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:205)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:67)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:60)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:167)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:60)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:54)
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
at org.gradle.internal.Factories$1.create(Factories.java:31)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)

View File

@@ -0,0 +1,45 @@
kotlin version: 2.0.21
error message: Failed connecting to the daemon in 4 retries
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:76)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:210)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:205)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:67)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:60)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:167)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:60)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:54)
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
at org.gradle.internal.Factories$1.create(Factories.java:31)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:263)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)

View File

@@ -0,0 +1,35 @@
kotlin version: 2.0.21
error message: Incremental compilation failed: E:\Download\Project\AutoRobot\Android\Robot\app\build\kotlin\compileDebugKotlin\cacheable\dirty-sources.txt: 另一个程序正在使用此文件,进程无法访问。
java.nio.file.FileSystemException: E:\Download\Project\AutoRobot\Android\Robot\app\build\kotlin\compileDebugKotlin\cacheable\dirty-sources.txt: 另一个程序正在使用此文件,进程无法访问。
at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:92)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:273)
at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:104)
at java.base/java.nio.file.Files.delete(Files.java:1152)
at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.deleteFile(CompilationTransaction.kt:198)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.doCompile(IncrementalCompilerRunner.kt:539)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl(IncrementalCompilerRunner.kt:423)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.tryCompileIncrementally$lambda$9$compile(IncrementalCompilerRunner.kt:249)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.tryCompileIncrementally(IncrementalCompilerRunner.kt:267)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:120)
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:675)
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:92)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1660)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)

View File

@@ -0,0 +1,4 @@
kotlin version: 2.0.21
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
1. Kotlin compile daemon is ready

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,36 @@
# AutoBot
#### Description
安卓手机自动运行脚本
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@@ -0,0 +1,37 @@
# AutoBot
#### 介绍
安卓手机自动运行脚本
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,54 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
}
android {
namespace = "com.joyd.autobot"
compileSdk = 36
defaultConfig {
applicationId = "com.joyd.autobot"
minSdk = 24
targetSdk = 36
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
}
dependencies {
implementation("androidx.preference:preference:1.2.1")
implementation("androidx.core:core-ktx:1.10.1")
implementation(libs.websocketclient)
implementation(libs.okhttp)
implementation("androidx.appcompat:appcompat:1.6.1")
implementation(libs.material)
implementation("androidx.activity:activity:1.8.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.cardview:cardview:1.0.0")
// 添加 JoydLib 库依赖
implementation(libs.joydlibdev)
testImplementation(libs.junit)
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

View File

@@ -0,0 +1,447 @@
2025-09-17 19:03:52.067 23529-23616 MainActivity com.joyd.autobot E WebSocket连接错误: failed to connect to /192.168.2.236 (port 8805) from /192.168.1.4 (port 34552) after 10000ms
2025-09-17 19:03:52.069 23529-23529 Compatibil...geReporter com.joyd.autobot D Compat change id reported: 147798919; UID 10301; state: ENABLED
2025-09-17 19:03:53.097 23529-23616 TrafficStats com.joyd.autobot D tagSocket(5) with statsTag=0xffffffff, statsUid=-1
2025-09-17 19:03:53.098 23529-23616 System.out com.joyd.autobot I [com.mediatek.cta.CtaAdapter]:check permission begin!
2025-09-17 19:03:56.225 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.236 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.253 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.273 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.296 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.309 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.310 23529-23529 MainActivity com.joyd.autobot D onPause()被调用,应用进入后台
2025-09-17 19:03:56.330 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.331 23529-23641 libMEOW com.joyd.autobot D meow new tls: 0xb4000079a1ecd040
2025-09-17 19:03:56.331 23529-23641 libMEOW com.joyd.autobot D applied 1 plugins for [com.joyd.autobot]:
2025-09-17 19:03:56.331 23529-23641 libMEOW com.joyd.autobot D plugin 1: [libMEOW_gift.so]:
2025-09-17 19:03:56.331 23529-23641 libMEOW com.joyd.autobot D meow delete tls: 0xb4000079a1ecd040
2025-09-17 19:03:56.339 23529-23563 ViewContentFactory com.joyd.autobot D initViewContentFetcherClass
2025-09-17 19:03:56.339 23529-23563 ContentCatcher com.joyd.autobot I ViewContentFetcher : ViewContentFetcher
2025-09-17 19:03:56.339 23529-23563 ViewContentFactory com.joyd.autobot D createInterceptor took 1ms
2025-09-17 19:03:56.339 23529-23529 IS_CTS_MODE com.joyd.autobot D false
2025-09-17 19:03:56.339 23529-23529 MULTI_WINDOW_ENABLED com.joyd.autobot D false
2025-09-17 19:03:56.340 23529-23563 ContentCatcher com.joyd.autobot I Interceptor : Catcher list invalid for com.joyd.autobot@com.joyd.autobot.SettingsActivity@98079379
2025-09-17 19:03:56.340 23529-23563 ContentCatcher com.joyd.autobot I Interceptor : Get featureInfo from config image_pick_mode
2025-09-17 19:03:56.340 23529-23563 ContentCatcher com.joyd.autobot I Interceptor : Get featureInfo from config pick_mode
2025-09-17 19:03:56.340 23529-23529 DecorView[] com.joyd.autobot D getWindowModeFromSystem windowmode is 1
2025-09-17 19:03:56.351 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.367 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.368 23529-23563 ContentCat...ListHelper com.joyd.autobot I blackList size: 13 package is com.joyd.autobot isInTaplusWhiteList: true
2025-09-17 19:03:56.371 23529-23560 libc com.joyd.autobot W Access denied finding property "ro.vendor.display.iris_x7.support"
2025-09-17 19:03:56.372 23529-23529 VRI[SettingsActivity] com.joyd.autobot D hardware acceleration = true, forceHwAccelerated = false
2025-09-17 19:03:56.380 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.393 23529-23529 BufferQueueConsumer com.joyd.autobot D [](id:5be900000001,api:0,p:-1,c:23529) connect: controlledByApp=false
2025-09-17 19:03:56.398 23529-23529 VRI[SettingsActivity] com.joyd.autobot D vri.reportNextDraw android.view.ViewRootImpl.performTraversals:3953 android.view.ViewRootImpl.doTraversal:2674 android.view.ViewRootImpl$TraversalRunnable.run:9867 android.view.Choreographer$CallbackRecord.run:1431 android.view.Choreographer$CallbackRecord.run:1439
2025-09-17 19:03:56.399 23529-23529 VRI[SettingsActivity] com.joyd.autobot D vri.Setup new sync id=0 syncSeqId=0
2025-09-17 19:03:56.400 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.408 23529-23560 libEGL com.joyd.autobot E pre_cache appList: com.android.calendar,com.android.contacts,com.android.fileexplorer,com.android.mms,com.android.settings,com.android.thememanager,com.miui.gallery,com.miui.notes,com.miui.player,com.miui.securitycenter,com.miui.video,com.miui.weather2
2025-09-17 19:03:56.425 4643-5173 ActivityManagerWrapper com.miui.home E getRecentTasks: mainTaskId=31617 userId=0 baseIntent=Intent { act=android.intent.action.MAIN flag=268435456 cmp=ComponentInfo{com.joyd.autobot/com.joyd.autobot.MainActivity} }
2025-09-17 19:03:56.429 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.429 23529-23560 BLASTBufferQueue com.joyd.autobot D [VRI[SettingsActivity]#1](f:0,a:1) acquireNextBufferLocked size=1080x2400 mFrameNumber=1 applyTransaction=true mTimestamp=143288805263693(auto) mPendingTransactions.size=0 graphicBufferId=101056285507591 transform=0
2025-09-17 19:03:56.430 23529-23560 Parcel com.joyd.autobot W Expecting binder but got null!
2025-09-17 19:03:56.431 23529-23529 VRI[SettingsActivity] com.joyd.autobot D vri.reportDrawFinished syncSeqId=0 android.view.ViewRootImpl.lambda$createSyncIfNeeded$4$android-view-ViewRootImpl:4021 android.view.ViewRootImpl$$ExternalSyntheticLambda1.run:6 android.os.Handler.handleCallback:942 android.os.Handler.dispatchMessage:99 android.os.Looper.loopOnce:211
2025-09-17 19:03:56.432 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.432 23529-23529 DecorView[] com.joyd.autobot D onWindowFocusChanged hasWindowFocus false
2025-09-17 19:03:56.437 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.448 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.453 4643-5173 ActivityManagerWrapper com.miui.home E getRecentTasks: mainTaskId=31617 userId=0 baseIntent=Intent { act=android.intent.action.MAIN flag=268435456 cmp=ComponentInfo{com.joyd.autobot/com.joyd.autobot.MainActivity} }
2025-09-17 19:03:56.454 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.465 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.466 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.466 23529-23529 DecorView[] com.joyd.autobot D onWindowFocusChanged hasWindowFocus true
2025-09-17 19:03:56.467 23529-23529 HandWritingStubImpl com.joyd.autobot I refreshLastKeyboardType: 1
2025-09-17 19:03:56.467 23529-23529 HandWritingStubImpl com.joyd.autobot I getCurrentKeyboardType: 1
2025-09-17 19:03:56.469 4041-4041 BaseInputMethodService com.sohu.inputmethod.sogou.xiaomi E onStartInput app:com.joyd.autobot restarting:false
2025-09-17 19:03:56.481 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.484 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.497 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.499 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.514 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.516 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.531 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.533 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.541 23529-23540 om.joyd.autobot com.joyd.autobot I Compiler allocated 5099KB to compile void android.view.ViewRootImpl.performTraversals()
2025-09-17 19:03:56.546 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.547 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.563 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.564 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.579 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.581 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.597 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.613 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.630 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.646 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.663 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.680 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.695 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.712 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.729 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.745 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.762 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.778 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.795 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.811 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.828 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.844 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.861 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.877 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.894 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.910 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.929 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:56.962 23529-23560 OpenGLRenderer com.joyd.autobot D endAllActiveAnimators on 0xb4000079bcaecb00 (RippleDrawable) with handle 0xb400007af02968a0
2025-09-17 19:03:56.985 23529-23529 BLASTBufferQueue com.joyd.autobot D [VRI[MainActivity]#0](f:0,a:1) destructor()
2025-09-17 19:03:56.985 23529-23529 BufferQueueConsumer com.joyd.autobot D [VRI[MainActivity]#0(BLAST Consumer)0](id:5be900000000,api:0,p:-1,c:23529) disconnect
2025-09-17 19:03:56.987 23529-23529 MainActivity com.joyd.autobot D onStop()被调用
2025-09-17 19:03:58.374 23529-23529 HandWritingStubImpl com.joyd.autobot I refreshLastKeyboardType: 1
2025-09-17 19:03:58.375 23529-23529 HandWritingStubImpl com.joyd.autobot I getCurrentKeyboardType: 1
2025-09-17 19:03:58.378 23529-23529 Compatibil...geReporter com.joyd.autobot D Compat change id reported: 163400105; UID 10301; state: ENABLED
2025-09-17 19:03:58.378 23529-23529 InputMethodManager com.joyd.autobot D showSoftInput() view=androidx.appcompat.widget.AppCompatEditText{ce5ac87 VFED..CL. .F.P..ID 0,81-948,206 #7f080219 app:id/web_socket_url_edit_text aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT
2025-09-17 19:03:58.379 4041-4041 BaseInputMethodService com.sohu.inputmethod.sogou.xiaomi E onStartInput app:com.joyd.autobot restarting:false
2025-09-17 19:03:58.387 4041-4041 BaseInputMethodService com.sohu.inputmethod.sogou.xiaomi E onStartInputView app:com.joyd.autobot restarting:false
2025-09-17 19:03:58.393 23529-23560 libc com.joyd.autobot W Access denied finding property "ro.vendor.display.iris_x7.support"
2025-09-17 19:03:58.394 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D hardware acceleration = true, forceHwAccelerated = false
2025-09-17 19:03:58.403 23529-23529 TextView com.joyd.autobot V sendCursorInfo support:true
2025-09-17 19:03:58.407 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:58.409 23529-23529 AssistStructure com.joyd.autobot I Flattened final assist data: 1568 bytes, containing 2 windows, 9 views
2025-09-17 19:03:58.418 23529-23529 BufferQueueConsumer com.joyd.autobot D [](id:5be900000002,api:0,p:-1,c:23529) connect: controlledByApp=false
2025-09-17 19:03:58.422 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportNextDraw android.view.ViewRootImpl.performTraversals:3953 android.view.ViewRootImpl.doTraversal:2674 android.view.ViewRootImpl$TraversalRunnable.run:9867 android.view.Choreographer$CallbackRecord.run:1431 android.view.Choreographer$CallbackRecord.run:1439
2025-09-17 19:03:58.422 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.Setup new sync id=0 syncSeqId=0
2025-09-17 19:03:58.434 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:58.434 23529-23560 BLASTBufferQueue com.joyd.autobot D [VRI[PopupWindow:18da57f]#2](f:0,a:1) acquireNextBufferLocked size=110x110 mFrameNumber=1 applyTransaction=true mTimestamp=143290810354155(auto) mPendingTransactions.size=0 graphicBufferId=101056285507594 transform=0
2025-09-17 19:03:58.436 23529-23560 Parcel com.joyd.autobot W Expecting binder but got null!
2025-09-17 19:03:58.436 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportDrawFinished syncSeqId=0 android.view.ViewRootImpl.lambda$createSyncIfNeeded$4$android-view-ViewRootImpl:4021 android.view.ViewRootImpl$$ExternalSyntheticLambda1.run:6 android.os.Handler.handleCallback:942 android.os.Handler.dispatchMessage:99 android.os.Looper.loopOnce:211
2025-09-17 19:03:58.437 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportNextDraw android.view.ViewRootImpl.handleResized:2047 android.view.ViewRootImpl.-$$Nest$mhandleResized:0 android.view.ViewRootImpl$ViewRootHandler.handleMessageImpl:6120 android.view.ViewRootImpl$ViewRootHandler.handleMessage:6084 android.os.Handler.dispatchMessage:106
2025-09-17 19:03:58.440 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.Setup new sync id=1 syncSeqId=0
2025-09-17 19:03:58.441 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportDrawFinished syncSeqId=0 android.view.ViewRootImpl.lambda$createSyncIfNeeded$4$android-view-ViewRootImpl:4021 android.view.ViewRootImpl$$ExternalSyntheticLambda1.run:6 android.os.Handler.handleCallback:942 android.os.Handler.dispatchMessage:99 android.os.Looper.loopOnce:211
2025-09-17 19:03:58.478 23529-23529 OnBackInvokedCallback com.joyd.autobot W OnBackInvokedCallback is not enabled for the application.
Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
2025-09-17 19:03:58.525 23529-23529 InsetsController com.joyd.autobot D show(ime(), fromIme=true)
2025-09-17 19:03:58.879 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:59.377 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:03:59.882 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:00.382 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:00.578 23529-23529 InputMethodManager com.joyd.autobot D showSoftInput() view=androidx.appcompat.widget.AppCompatEditText{ce5ac87 VFED..CL. .F.P.... 0,81-948,206 #7f080219 app:id/web_socket_url_edit_text aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT
2025-09-17 19:04:00.587 23529-23529 View com.joyd.autobot D [Warning] assignParent to null: this = android.widget.PopupWindow$PopupDecorView{70a9e49 V.E...... R....... 0,0-110,110 aid=1073741831}
2025-09-17 19:04:00.587 23529-23529 BLASTBufferQueue com.joyd.autobot D [VRI[PopupWindow:18da57f]#2](f:0,a:1) destructor()
2025-09-17 19:04:00.587 23529-23529 BufferQueueConsumer com.joyd.autobot D [VRI[PopupWindow:18da57f]#2(BLAST Consumer)2](id:5be900000002,api:0,p:-1,c:23529) disconnect
2025-09-17 19:04:00.622 23529-23529 InsetsController com.joyd.autobot D show(ime(), fromIme=true)
2025-09-17 19:04:00.633 23529-23560 libc com.joyd.autobot W Access denied finding property "ro.vendor.display.iris_x7.support"
2025-09-17 19:04:00.634 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D hardware acceleration = true, forceHwAccelerated = false
2025-09-17 19:04:00.658 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:00.673 23529-23529 BufferQueueConsumer com.joyd.autobot D [](id:5be900000003,api:0,p:-1,c:23529) connect: controlledByApp=false
2025-09-17 19:04:00.680 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportNextDraw android.view.ViewRootImpl.performTraversals:3953 android.view.ViewRootImpl.doTraversal:2674 android.view.ViewRootImpl$TraversalRunnable.run:9867 android.view.Choreographer$CallbackRecord.run:1431 android.view.Choreographer$CallbackRecord.run:1439
2025-09-17 19:04:00.681 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.Setup new sync id=0 syncSeqId=0
2025-09-17 19:04:00.685 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:00.685 23529-23560 BLASTBufferQueue com.joyd.autobot D [VRI[PopupWindow:18da57f]#3](f:0,a:1) acquireNextBufferLocked size=110x110 mFrameNumber=1 applyTransaction=true mTimestamp=143293061200232(auto) mPendingTransactions.size=0 graphicBufferId=101056285507599 transform=0
2025-09-17 19:04:00.686 23529-23560 Parcel com.joyd.autobot W Expecting binder but got null!
2025-09-17 19:04:00.688 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportDrawFinished syncSeqId=0 android.view.ViewRootImpl.lambda$createSyncIfNeeded$4$android-view-ViewRootImpl:4021 android.view.ViewRootImpl$$ExternalSyntheticLambda1.run:6 android.os.Handler.handleCallback:942 android.os.Handler.dispatchMessage:99 android.os.Looper.loopOnce:211
2025-09-17 19:04:00.690 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportNextDraw android.view.ViewRootImpl.handleResized:2047 android.view.ViewRootImpl.-$$Nest$mhandleResized:0 android.view.ViewRootImpl$ViewRootHandler.handleMessageImpl:6120 android.view.ViewRootImpl$ViewRootHandler.handleMessage:6084 android.os.Handler.dispatchMessage:106
2025-09-17 19:04:00.692 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.Setup new sync id=1 syncSeqId=0
2025-09-17 19:04:00.694 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportDrawFinished syncSeqId=0 android.view.ViewRootImpl.lambda$createSyncIfNeeded$4$android-view-ViewRootImpl:4021 android.view.ViewRootImpl$$ExternalSyntheticLambda1.run:6 android.os.Handler.handleCallback:942 android.os.Handler.dispatchMessage:99 android.os.Looper.loopOnce:211
2025-09-17 19:04:01.124 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:01.638 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:02.126 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:02.191 23529-23529 InputMethodManager com.joyd.autobot D showSoftInput() view=androidx.appcompat.widget.AppCompatEditText{ce5ac87 VFED..CL. .F.P.... 0,81-948,206 #7f080219 app:id/web_socket_url_edit_text aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT
2025-09-17 19:04:02.208 23529-23529 View com.joyd.autobot D [Warning] assignParent to null: this = android.widget.PopupWindow$PopupDecorView{2a3fa67 V.E...... R....... 0,0-110,110}
2025-09-17 19:04:02.209 23529-23529 BLASTBufferQueue com.joyd.autobot D [VRI[PopupWindow:18da57f]#3](f:0,a:1) destructor()
2025-09-17 19:04:02.209 23529-23529 BufferQueueConsumer com.joyd.autobot D [VRI[PopupWindow:18da57f]#3(BLAST Consumer)3](id:5be900000003,api:0,p:-1,c:23529) disconnect
2025-09-17 19:04:02.237 23529-23529 InsetsController com.joyd.autobot D show(ime(), fromIme=true)
2025-09-17 19:04:02.638 23529-23560 libc com.joyd.autobot W Access denied finding property "ro.vendor.display.iris_x7.support"
2025-09-17 19:04:02.639 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D hardware acceleration = true, forceHwAccelerated = false
2025-09-17 19:04:02.663 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:02.682 23529-23529 BufferQueueConsumer com.joyd.autobot D [](id:5be900000004,api:0,p:-1,c:23529) connect: controlledByApp=false
2025-09-17 19:04:02.688 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportNextDraw android.view.ViewRootImpl.performTraversals:3953 android.view.ViewRootImpl.doTraversal:2674 android.view.ViewRootImpl$TraversalRunnable.run:9867 android.view.Choreographer$CallbackRecord.run:1431 android.view.Choreographer$CallbackRecord.run:1439
2025-09-17 19:04:02.688 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.Setup new sync id=0 syncSeqId=0
2025-09-17 19:04:02.693 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:02.694 23529-23560 BLASTBufferQueue com.joyd.autobot D [VRI[PopupWindow:18da57f]#4](f:0,a:1) acquireNextBufferLocked size=110x110 mFrameNumber=1 applyTransaction=true mTimestamp=143295069356924(auto) mPendingTransactions.size=0 graphicBufferId=101056285507603 transform=0
2025-09-17 19:04:02.694 23529-23560 Parcel com.joyd.autobot W Expecting binder but got null!
2025-09-17 19:04:02.696 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportDrawFinished syncSeqId=0 android.view.ViewRootImpl.lambda$createSyncIfNeeded$4$android-view-ViewRootImpl:4021 android.view.ViewRootImpl$$ExternalSyntheticLambda1.run:6 android.os.Handler.handleCallback:942 android.os.Handler.dispatchMessage:99 android.os.Looper.loopOnce:211
2025-09-17 19:04:02.698 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportNextDraw android.view.ViewRootImpl.handleResized:2047 android.view.ViewRootImpl.-$$Nest$mhandleResized:0 android.view.ViewRootImpl$ViewRootHandler.handleMessageImpl:6120 android.view.ViewRootImpl$ViewRootHandler.handleMessage:6084 android.os.Handler.dispatchMessage:106
2025-09-17 19:04:02.699 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.Setup new sync id=1 syncSeqId=0
2025-09-17 19:04:02.701 23529-23529 VRI[PopupW...w:18da57f] com.joyd.autobot D vri.reportDrawFinished syncSeqId=0 android.view.ViewRootImpl.lambda$createSyncIfNeeded$4$android-view-ViewRootImpl:4021 android.view.ViewRootImpl$$ExternalSyntheticLambda1.run:6 android.os.Handler.handleCallback:942 android.os.Handler.dispatchMessage:99 android.os.Looper.loopOnce:211
2025-09-17 19:04:03.110 23529-23616 MainActivity com.joyd.autobot E WebSocket连接错误: failed to connect to /192.168.2.236 (port 8805) from /192.168.1.4 (port 34560) after 10000ms
2025-09-17 19:04:03.139 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.370 23529-23529 BufferQueueConsumer com.joyd.autobot D [](id:5be900000005,api:0,p:-1,c:23529) connect: controlledByApp=false
2025-09-17 19:04:03.373 23529-23560 libc com.joyd.autobot W Access denied finding property "ro.vendor.display.iris_x7.support"
2025-09-17 19:04:03.375 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.416 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.416 23529-23560 BLASTBufferQueue com.joyd.autobot D [magnifier surface#5](f:0,a:1) acquireNextBufferLocked size=297x154 mFrameNumber=1 applyTransaction=true mTimestamp=143295791965847(auto) mPendingTransactions.size=0 graphicBufferId=101056285507604 transform=0
2025-09-17 19:04:03.416 23529-23560 Parcel com.joyd.autobot W Expecting binder but got null!
2025-09-17 19:04:03.418 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.420 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.424 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.549 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.556 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.560 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.562 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.571 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.580 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.583 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.586 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.598 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.600 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.604 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.607 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.612 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.614 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.618 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.621 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.629 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.631 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.634 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.637 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.641 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.643 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.646 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.647 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.652 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.655 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.657 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:03.658 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:03.662 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.025 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.031 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.033 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.035 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.037 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.043 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.046 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.048 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.049 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.052 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.058 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.062 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.064 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.066 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.078 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.079 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.083 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.091 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.093 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.097 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.103 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.110 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.112 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.116 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.120 23529-23616 TrafficStats com.joyd.autobot D tagSocket(101) with statsTag=0xffffffff, statsUid=-1
2025-09-17 19:04:04.120 23529-23616 System.out com.joyd.autobot I [com.mediatek.cta.CtaAdapter]:check permission begin!
2025-09-17 19:04:04.121 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.124 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.126 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.130 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.134 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.143 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.145 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.150 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.154 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.158 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.159 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.176 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.177 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.181 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.191 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.192 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.197 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.201 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.207 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.208 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.213 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.217 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.223 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.225 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.230 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.234 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.242 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.244 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.251 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.255 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.259 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.261 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.266 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.270 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.274 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.275 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.279 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.284 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.292 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.294 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.298 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.303 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.306 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.308 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.313 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.319 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.323 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.325 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.335 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.338 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.342 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.344 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.350 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.352 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.356 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.358 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.362 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.366 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.374 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.376 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.381 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.384 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.389 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.391 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.395 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.400 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.406 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.408 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.411 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.415 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.423 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.424 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.440 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.603 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.610 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.612 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.614 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.618 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.621 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.625 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.627 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.628 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.631 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.636 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.640 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.642 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.643 23529-23560 om.joyd.autobot com.joyd.autobot E == MALI DEBUG ===eglp_winsys_populate_image_templates ==12288
2025-09-17 19:04:04.653 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:04.931 23529-23529 BLASTBufferQueue com.joyd.autobot D [magnifier surface#5](f:0,a:1) destructor()
2025-09-17 19:04:04.931 23529-23529 BufferQueueConsumer com.joyd.autobot D [magnifier surface#5(BLAST Consumer)5](id:5be900000005,api:0,p:-1,c:23529) disconnect
2025-09-17 19:04:05.461 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:05.959 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:06.310 23529-23529 View com.joyd.autobot D [Warning] assignParent to null: this = android.widget.PopupWindow$PopupDecorView{38602b0 V.E...... R.....I. 0,0-110,110}
2025-09-17 19:04:06.310 23529-23529 BLASTBufferQueue com.joyd.autobot D [VRI[PopupWindow:18da57f]#4](f:0,a:1) destructor()
2025-09-17 19:04:06.311 23529-23529 BufferQueueConsumer com.joyd.autobot D [VRI[PopupWindow:18da57f]#4(BLAST Consumer)4](id:5be900000004,api:0,p:-1,c:23529) disconnect
2025-09-17 19:04:06.331 23529-23529 VRI[SettingsActivity] com.joyd.autobot V [ANR Warning]Input routeing takes more than 6000ms since 1970-01-01 08:00:00.000, this = com.mediatek.view.impl.ViewDebugManagerImpl@900f529
2025-09-17 19:04:06.331 23529-23529 VRI[SettingsActivity] com.joyd.autobot V Input event delivered to android.view.ViewRootImpl$EarlyPostImeInputStage@7368a16 at 2025-09-17 19:04:06.298
2025-09-17 19:04:06.331 23529-23529 VRI[SettingsActivity] com.joyd.autobot V Input event delivered to android.view.ViewRootImpl$ViewPostImeInputStage@637f584 at 2025-09-17 19:04:06.298
2025-09-17 19:04:06.332 23529-23529 VRI[SettingsActivity] com.joyd.autobot V Input event delivered to android.view.ViewRootImpl$NativePostImeInputStage@34faf97 at 2025-09-17 19:04:06.298
2025-09-17 19:04:06.332 23529-23529 VRI[SettingsActivity] com.joyd.autobot V Input event delivered to android.view.ViewRootImpl$SyntheticInputStage@a113769 at 2025-09-17 19:04:06.326
2025-09-17 19:04:06.333 23529-23529 VRI[SettingsActivity] com.joyd.autobot V [ANR Warning]Input routeing takes more than 6000ms since 1970-01-01 08:00:00.000, this = com.mediatek.view.impl.ViewDebugManagerImpl@900f529
2025-09-17 19:04:06.333 23529-23529 VRI[SettingsActivity] com.joyd.autobot V Input event delivered to android.view.ViewRootImpl$EarlyPostImeInputStage@7368a16 at 2025-09-17 19:04:06.332
2025-09-17 19:04:06.333 23529-23529 VRI[SettingsActivity] com.joyd.autobot V Input event delivered to android.view.ViewRootImpl$ViewPostImeInputStage@637f584 at 2025-09-17 19:04:06.332
2025-09-17 19:04:06.333 23529-23529 VRI[SettingsActivity] com.joyd.autobot V Input event delivered to android.view.ViewRootImpl$NativePostImeInputStage@34faf97 at 2025-09-17 19:04:06.332
2025-09-17 19:04:06.333 23529-23529 VRI[SettingsActivity] com.joyd.autobot V Input event delivered to android.view.ViewRootImpl$SyntheticInputStage@a113769 at 2025-09-17 19:04:06.333
2025-09-17 19:04:06.340 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:06.837 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:07.353 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:07.847 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:08.350 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:08.443 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:08.935 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:09.448 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:09.942 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:10.451 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:10.948 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:11.445 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:11.951 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:12.366 23529-23529 Compatibil...geReporter com.joyd.autobot D Compat change id reported: 150939131; UID 10301; state: ENABLED
2025-09-17 19:04:12.446 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:12.940 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:13.454 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:13.948 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.130 23529-23616 MainActivity com.joyd.autobot E WebSocket连接错误: failed to connect to /192.168.2.236 (port 8805) from /192.168.1.4 (port 34564) after 10000ms
2025-09-17 19:04:14.349 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.359 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.376 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.392 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.409 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.418 23529-23529 SettingsActivity com.joyd.autobot D 保存WebSocket地址: ws://192.168.1.236:8805
2025-09-17 19:04:14.428 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.445 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.448 23529-23563 ContentCat...ListHelper com.joyd.autobot I blackList size: 13 package is com.joyd.autobot isInTaplusWhiteList: true
2025-09-17 19:04:14.459 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.466 23529-23529 BufferQueueConsumer com.joyd.autobot D [](id:5be900000006,api:0,p:-1,c:23529) connect: controlledByApp=false
2025-09-17 19:04:14.467 23529-23529 VRI[MainActivity] com.joyd.autobot D vri.reportNextDraw android.view.ViewRootImpl.performTraversals:3953 android.view.ViewRootImpl.doTraversal:2674 android.view.ViewRootImpl$TraversalRunnable.run:9867 android.view.Choreographer$CallbackRecord.run:1431 android.view.Choreographer$CallbackRecord.run:1439
2025-09-17 19:04:14.467 23529-23529 VRI[MainActivity] com.joyd.autobot D vri.Setup new sync id=1 syncSeqId=0
2025-09-17 19:04:14.478 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.489 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.492 23529-23560 BLASTBufferQueue com.joyd.autobot D [VRI[MainActivity]#6](f:0,a:1) acquireNextBufferLocked size=1080x2400 mFrameNumber=1 applyTransaction=true mTimestamp=143306864991925(auto) mPendingTransactions.size=0 graphicBufferId=101056285507610 transform=0
2025-09-17 19:04:14.494 23529-23529 VRI[MainActivity] com.joyd.autobot D vri.reportDrawFinished syncSeqId=0 android.view.ViewRootImpl.lambda$createSyncIfNeeded$4$android-view-ViewRootImpl:4021 android.view.ViewRootImpl$$ExternalSyntheticLambda1.run:6 android.os.Handler.handleCallback:942 android.os.Handler.dispatchMessage:99 android.os.Looper.loopOnce:211
2025-09-17 19:04:14.497 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.499 23529-23529 DecorView[] com.joyd.autobot D onWindowFocusChanged hasWindowFocus false
2025-09-17 19:04:14.510 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.525 23529-23529 DecorView[] com.joyd.autobot D onWindowFocusChanged hasWindowFocus true
2025-09-17 19:04:14.526 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.528 23529-23529 HandWritingStubImpl com.joyd.autobot I refreshLastKeyboardType: 1
2025-09-17 19:04:14.529 23529-23529 HandWritingStubImpl com.joyd.autobot I getCurrentKeyboardType: 1
2025-09-17 19:04:14.531 4041-4041 BaseInputMethodService com.sohu.inputmethod.sogou.xiaomi E onStartInput app:com.joyd.autobot restarting:false
2025-09-17 19:04:14.548 4643-5173 ActivityManagerWrapper com.miui.home E getRecentTasks: mainTaskId=31617 userId=0 baseIntent=Intent { act=android.intent.action.MAIN flag=268435456 cmp=ComponentInfo{com.joyd.autobot/com.joyd.autobot.MainActivity} }
2025-09-17 19:04:14.553 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.556 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.559 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.563 4643-5173 ActivityManagerWrapper com.miui.home E getRecentTasks: mainTaskId=31617 userId=0 baseIntent=Intent { act=android.intent.action.MAIN flag=268435456 cmp=ComponentInfo{com.joyd.autobot/com.joyd.autobot.MainActivity} }
2025-09-17 19:04:14.567 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.575 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.580 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.593 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.599 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.608 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.614 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.625 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.628 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.643 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.644 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.658 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.674 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.690 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.707 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.724 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.740 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.757 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.773 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.790 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.806 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.821 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.839 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.856 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.872 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.889 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.905 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.922 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.938 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.955 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.971 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:14.988 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:15.004 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:15.035 23529-23560 OpenGLRenderer com.joyd.autobot D endAllActiveAnimators on 0xb4000079a4dce100 (RippleDrawable) with handle 0xb4000079bc878e20
2025-09-17 19:04:15.043 23529-23529 BLASTBufferQueue com.joyd.autobot D [VRI[SettingsActivity]#1](f:0,a:1) destructor()
2025-09-17 19:04:15.044 23529-23529 BufferQueueConsumer com.joyd.autobot D [VRI[SettingsActivity]#1(BLAST Consumer)1](id:5be900000001,api:0,p:-1,c:23529) disconnect
2025-09-17 19:04:15.052 23529-23529 View com.joyd.autobot D [Warning] assignParent to null: this = DecorView@5f1e3d1[SettingsActivity]
2025-09-17 19:04:15.141 23529-23616 TrafficStats com.joyd.autobot D tagSocket(78) with statsTag=0xffffffff, statsUid=-1
2025-09-17 19:04:15.141 23529-23616 System.out com.joyd.autobot I [com.mediatek.cta.CtaAdapter]:check permission begin!
2025-09-17 19:04:16.042 23529-23529 MainActivity com.joyd.autobot D onPause()被调用,应用进入后台
2025-09-17 19:04:16.070 4643-5173 ActivityManagerWrapper com.miui.home E getRecentTasks: mainTaskId=31617 userId=0 baseIntent=Intent { act=android.intent.action.MAIN flag=268435456 cmp=ComponentInfo{com.joyd.autobot/com.joyd.autobot.MainActivity} }
2025-09-17 19:04:16.081 23529-23529 DecorView[] com.joyd.autobot D onWindowFocusChanged hasWindowFocus false
2025-09-17 19:04:16.124 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:16.129 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:16.140 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:16.148 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:16.165 4643-5173 ActivityManagerWrapper com.miui.home E getRecentTasks: mainTaskId=31617 userId=0 baseIntent=Intent { act=android.intent.action.MAIN flag=268435456 cmp=ComponentInfo{com.joyd.autobot/com.joyd.autobot.MainActivity} }
2025-09-17 19:04:16.171 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:16.182 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:16.195 23529-23560 gralloc4 com.joyd.autobot E Empty SMPTE 2094-40 data
2025-09-17 19:04:16.464 23529-23529 BLASTBufferQueue com.joyd.autobot D [VRI[MainActivity]#6](f:0,a:1) destructor()
2025-09-17 19:04:16.464 23529-23529 BufferQueueConsumer com.joyd.autobot D [VRI[MainActivity]#6(BLAST Consumer)6](id:5be900000006,api:0,p:-1,c:23529) disconnect
2025-09-17 19:04:16.467 23529-23529 MainActivity com.joyd.autobot D onStop()被调用
2025-09-17 19:04:21.628 23529-23541 om.joyd.autobot com.joyd.autobot W Cleared Reference was only reachable from finalizer (only reported once)
2025-09-17 19:04:21.638 23529-23541 om.joyd.autobot com.joyd.autobot I This is non sticky GC, maxfree is 8388608 minfree is 524288
2025-09-17 19:04:25.170 23529-23616 MainActivity com.joyd.autobot E WebSocket连接错误: failed to connect to /192.168.2.236 (port 8805) from /192.168.1.4 (port 34588) after 10000ms
2025-09-17 19:04:26.214 23529-23616 TrafficStats com.joyd.autobot D tagSocket(78) with statsTag=0xffffffff, statsUid=-1
2025-09-17 19:04:26.215 23529-23616 System.out com.joyd.autobot I [com.mediatek.cta.CtaAdapter]:check permission begin!
2025-09-17 19:04:36.228 23529-23616 MainActivity com.joyd.autobot E WebSocket连接错误: failed to connect to /192.168.2.236 (port 8805) from /192.168.1.4 (port 34592) after 10000ms
2025-09-17 19:04:37.249 23529-23616 TrafficStats com.joyd.autobot D tagSocket(78) with statsTag=0xffffffff, statsUid=-1
2025-09-17 19:04:37.249 23529-23616 System.out com.joyd.autobot I [com.mediatek.cta.CtaAdapter]:check permission begin!
2025-09-17 19:04:47.263 23529-23616 MainActivity com.joyd.autobot E WebSocket连接错误: failed to connect to /192.168.2.236 (port 8805) from /192.168.1.4 (port 34756) after 10000ms
2025-09-17 19:04:48.277 23529-23616 TrafficStats com.joyd.autobot D tagSocket(78) with statsTag=0xffffffff, statsUid=-1
2025-09-17 19:04:48.278 23529-23616 System.out com.joyd.autobot I [com.mediatek.cta.CtaAdapter]:check permission begin!
2025-09-17 19:04:58.287 23529-23616 MainActivity com.joyd.autobot E WebSocket连接错误: failed to connect to /192.168.2.236 (port 8805) from /192.168.1.4 (port 34782) after 10000ms
2025-09-17 19:04:59.307 23529-23616 TrafficStats com.joyd.autobot D tagSocket(78) with statsTag=0xffffffff, statsUid=-1
2025-09-17 19:04:59.307 23529-23616 System.out com.joyd.autobot I [com.mediatek.cta.CtaAdapter]:check permission begin!

View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,24 @@
package com.joyd.autobot
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.joyd.autobot", appContext.packageName)
}
}

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 添加必要的权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<!-- 用于支持截屏功能 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:minSdkVersion="33" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" android:minSdkVersion="34" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AutoBot"
tools:replace="android:label">
<!-- 添加系统属性访问兼容性配置 -->
<meta-data
android:name="android.content.APP_RESOURCE_ACCESS_FIX"
android:value="true" />
<!-- 针对SELinux策略的兼容性配置 -->
<meta-data
android:name="android.content.SELINUX_COMPAT_MODE"
android:value="relaxed" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 注册设置Activity -->
<activity
android:name=".SettingsActivity"
android:exported="false" />
<!-- 注册前台服务 -->
<service
android:name="com.joyd.autobot.WebSocketForegroundService"
android:exported="false"
android:foregroundServiceType="mediaProjection" />
</application>
</manifest>

View File

@@ -0,0 +1,676 @@
package com.joyd.autobot
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.BroadcastReceiver
import android.content.pm.PackageManager
import android.content.SharedPreferences
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.activity.result.contract.ActivityResultContracts
import com.joyd.joydlib.io.WebSocketClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okio.ByteString
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
class MainActivity : AppCompatActivity(), WebSocketForegroundService.Companion.ServiceReadyCallback {
private val TAG = "MainActivity"
private val SCREENSHOT_COMMAND = "screenshot"
private val REQUEST_NOTIFICATION_PERMISSION = 1002
// 定义截图数据广播的action
private val SCREENSHOT_DATA_ACTION = "com.joyd.autobot.SCREENSHOT_DATA"
private val SCREENSHOT_DATA_EXTRA = "screenshot_data"
// 定义MediaProjection权限请求广播的action
private val MEDIA_PROJECTION_PERMISSION_REQUIRED = "com.joyd.autobot.MEDIA_PROJECTION_PERMISSION_REQUIRED"
private lateinit var connectButton: Button
private lateinit var connectionStatusIndicator: View
private lateinit var connectionStatusText: TextView
private lateinit var settingsButton: Button
private lateinit var webSocketUrl: String
private var webSocketClient: WebSocketClient? = null
private var isConnected = false
// 重连延迟常量 - 保留此常量用于连接断开后的重连逻辑
private val RECONNECT_DELAY_MS = 5000L // 重连延迟5秒
// 重连状态标志
private val isReconnecting = AtomicBoolean(false)
// 处理异步事件的Handler
private lateinit var handler: Handler
// UI组件引用
private var screenshotButton: Button? = null
// 创建截图数据广播接收器
private val screenshotBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == SCREENSHOT_DATA_ACTION) {
val screenshotData = intent.getByteArrayExtra(SCREENSHOT_DATA_EXTRA)
if (screenshotData != null) {
Log.d(TAG, "接收到截图数据,大小: ${screenshotData.size} bytes")
// 发送截图数据到服务端
sendScreenshotData(screenshotData)
} else {
Log.e(TAG, "接收到的截图数据为null")
}
} else if (intent?.action == MEDIA_PROJECTION_PERMISSION_REQUIRED) {
// 接收到需要重新请求MediaProjection权限的广播
Log.d(TAG, "接收到需要重新请求MediaProjection权限的广播")
runOnUiThread {
Toast.makeText(this@MainActivity, "需要重新请求屏幕捕获权限以继续截图功能", Toast.LENGTH_SHORT).show()
requestScreenshotPermission()
}
}
}
}
// Activity Result API launcher for media projection
private val mediaProjectionLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK && it.data != null) {
Log.d(TAG, "用户授予了屏幕捕获权限")
WebSocketForegroundService.setMediaProjection(this, it.resultCode, it.data!!)
} else {
// 用户拒绝了屏幕捕获权限
Log.d(TAG, "用户拒绝了屏幕捕获权限resultCode: ${it.resultCode}")
Toast.makeText(this, "需要屏幕捕获权限才能执行截图操作", Toast.LENGTH_SHORT).show()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(TAG, "onCreate()被调用")
// 初始化Handler
handler = Handler(Looper.getMainLooper())
// 初始化UI组件
initUI()
// 从SharedPreferences获取配置的WebSocket URL
val sharedPreferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this)
val defaultUrl = getString(R.string.web_socket_url)
webSocketUrl = sharedPreferences.getString(getString(R.string.pref_key_web_socket_url), defaultUrl) ?: defaultUrl
Log.d(TAG, "从配置获取WebSocket URL: $webSocketUrl")
// 初始化WebSocket客户端
initWebSocketClient()
// 检查并请求通知权限
checkNotificationPermission()
// 注册截图数据广播接收器
registerScreenshotBroadcastReceiver()
}
// 注册截图数据广播接收器
private fun registerScreenshotBroadcastReceiver() {
val filter = IntentFilter()
filter.addAction(SCREENSHOT_DATA_ACTION)
filter.addAction(MEDIA_PROJECTION_PERMISSION_REQUIRED)
ContextCompat.registerReceiver(
this,
screenshotBroadcastReceiver,
filter,
ContextCompat.RECEIVER_NOT_EXPORTED
)
Log.d(TAG, "截图数据广播接收器和MediaProjection权限请求广播接收器已注册")
}
// 注销截图数据广播接收器
private fun unregisterScreenshotBroadcastReceiver() {
try {
unregisterReceiver(screenshotBroadcastReceiver)
Log.d(TAG, "截图数据广播接收器已注销")
} catch (e: Exception) {
Log.e(TAG, "注销广播接收器异常: ${e.message}", e)
}
}
private fun initUI() {
connectButton = findViewById<Button>(R.id.connect_button)
connectionStatusIndicator = findViewById<View>(R.id.connection_status_indicator)
connectionStatusText = findViewById<TextView>(R.id.connection_status_text)
settingsButton = findViewById<Button>(R.id.settings_btn)
// 初始状态设置为未连接
updateConnectionStatus(false)
// 设置连接按钮点击事件
setupConnectButton()
// 设置设置按钮点击事件
setupSettingsButton()
}
private fun checkNotificationPermission() {
// Android 13及以上需要通知权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "通知权限未授予,请求权限")
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), REQUEST_NOTIFICATION_PERMISSION)
} else {
Log.d(TAG, "通知权限已授予")
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_NOTIFICATION_PERMISSION -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "用户授予了通知权限")
} else {
Log.w(TAG, "用户拒绝了通知权限")
Toast.makeText(this, "需要通知权限以在后台保持WebSocket连接", Toast.LENGTH_SHORT).show()
}
}
}
}
private fun initWebSocketClient() {
try {
Log.d(TAG, "开始初始化WebSocket客户端")
// 创建WebSocket客户端实例
webSocketClient = WebSocketClient(webSocketUrl)
if (webSocketClient == null) {
Log.e(TAG, "WebSocketClient创建失败对象为null")
return
}
Log.d(TAG, "WebSocket客户端创建成功: $webSocketClient")
// 配置重连参数
val reconnectConfigResult = webSocketClient?.setReconnectConfig(
maxAttempts = 10, // 最大重连次数
baseDelayMs = 1000L, // 基础重连延迟(毫秒)
maxDelayMs = 30000L // 最大重连延迟(毫秒)
)
Log.d(TAG, "WebSocket重连参数配置完成结果: $reconnectConfigResult")
// 设置消息接收回调
val messageCallbackResult = webSocketClient?.setOnMessageCallback {
// 处理接收到的文本消息
Log.d(TAG, "收到WebSocket消息: $it")
// 检查是否是截屏命令
if (it == SCREENSHOT_COMMAND) {
Log.d(TAG, "收到截屏命令,开始执行截屏操作")
// 在后台线程执行截屏操作
Thread {
try {
takeScreenshot()
} catch (e: Exception) {
Log.e(TAG, "执行截屏操作异常: ${e.message}", e)
}
}.start()
} else {
runOnUiThread {
Toast.makeText(this@MainActivity, "收到消息: $it", Toast.LENGTH_SHORT).show()
// 收到消息意味着连接成功如果UI还显示未连接强制更新UI
if (!isConnected) {
Log.d(TAG, "收到消息但isConnected为false强制更新UI为连接状态")
isConnected = true
updateConnectionStatus(true)
}
}
}
}
Log.d(TAG, "WebSocket消息接收回调设置完成结果: $messageCallbackResult")
// 设置连接状态变化回调 - 完善实现更新连接状态和UI
val stateCallbackResult = webSocketClient?.setOnStateChangeCallback { state ->
// 处理连接状态变化
Log.d(TAG, "WebSocket连接状态变化: $state")
// 状态变化日志
val statusMessage = when(state) {
WebSocketClient.ConnectionState.Disconnected -> "连接已断开"
WebSocketClient.ConnectionState.Connecting -> "正在连接"
WebSocketClient.ConnectionState.Connected -> "WebSocket连接成功"
WebSocketClient.ConnectionState.Paused -> "连接已暂停"
else -> "未知状态"
}
Log.d(TAG, "显示Toast消息: $statusMessage")
// 根据实际连接状态更新isConnected变量和UI
runOnUiThread {
Toast.makeText(this@MainActivity, statusMessage, Toast.LENGTH_SHORT).show()
// 只有当状态为Connected时才更新UI为已连接
val newConnectionStatus = (state == WebSocketClient.ConnectionState.Connected)
if (isConnected != newConnectionStatus) {
isConnected = newConnectionStatus
updateConnectionStatus(isConnected)
}
}
}
Log.d(TAG, "WebSocket连接状态回调设置完成结果: $stateCallbackResult")
// 设置错误回调
val errorCallbackResult = webSocketClient?.setOnErrorCallback {
Log.e(TAG, "WebSocket连接错误: ${it?.message}")
runOnUiThread {
val errorMsg = it?.message ?: "未知错误"
Toast.makeText(this@MainActivity, "WebSocket连接错误: $errorMsg", Toast.LENGTH_SHORT).show()
}
}
Log.d(TAG, "WebSocket错误回调设置完成")
Log.d(TAG, "WebSocket客户端初始化完成")
} catch (e: Exception) {
Log.e(TAG, "初始化WebSocket失败: ${e.message}", e)
runOnUiThread {
Toast.makeText(this, "初始化WebSocket失败: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
/**
* 执行截屏操作
* 现在通过前台服务请求截图
*/
private fun takeScreenshot() {
Log.d(TAG, "takeScreenshot方法被调用")
// 检查WebSocket连接状态
if (!isConnected) {
Log.w(TAG, "WebSocket未连接无法发送截图")
runOnUiThread {
Toast.makeText(this, "WebSocket未连接请先连接", Toast.LENGTH_SHORT).show()
}
return
}
// 获取当前服务实例状态
val service = WebSocketForegroundService.getInstance()
Log.d(TAG, "当前服务实例状态: $service")
// 确保前台服务已启动
if (service == null) {
Log.d(TAG, "前台服务未启动,先启动服务")
WebSocketForegroundService.startService(this)
Log.d(TAG, "前台服务启动命令已发送")
// 增加尝试次数计数器
val attempts = AtomicInteger(0)
val maxAttempts = 5
// 延迟尝试截图,给服务启动时间
val handler = Handler(Looper.getMainLooper())
val runnable = object : Runnable {
override fun run() {
val currentAttempt = attempts.incrementAndGet()
if (currentAttempt <= maxAttempts) {
val currentService = WebSocketForegroundService.getInstance()
Log.d(TAG, "尝试 #$currentAttempt 检查服务状态: $currentService")
if (currentService == null) {
Log.d(TAG, "服务仍未启动,$currentAttempt 秒后再次尝试")
handler.postDelayed(this, 1000)
} else {
Log.d(TAG, "服务已成功启动,开始截图操作")
takeScreenshot()
}
} else {
Log.e(TAG, "服务启动超时,无法完成截图操作")
runOnUiThread {
Toast.makeText(this@MainActivity, "服务启动超时,截图失败", Toast.LENGTH_SHORT).show()
}
}
}
}
handler.postDelayed(runnable, 1000)
return
}
Log.d(TAG, "服务实例已获取正在检查MediaProjection状态")
// 直接通过前台服务请求截图
try {
// 先检查是否已有可用的MediaProjection实例
if (WebSocketForegroundService.hasActiveMediaProjection()) {
Log.d(TAG, "发现已有可用的MediaProjection实例直接请求截图")
val currentService = WebSocketForegroundService.getInstance()
Log.d(TAG, "获取到的前台服务实例: $currentService")
if (currentService != null) {
Log.d(TAG, "调用服务的requestScreenshotSafely方法")
currentService.requestScreenshotSafely()
} else {
Log.e(TAG, "前台服务实例获取失败,无法请求截图")
runOnUiThread {
Toast.makeText(this@MainActivity, "截图服务不可用", Toast.LENGTH_SHORT).show()
}
}
return
} else {
Log.d(TAG, "没有可用的MediaProjection实例")
}
// 如果没有可用的MediaProjection实例启动服务并请求权限
Log.d(TAG, "准备启动服务并请求MediaProjection权限")
WebSocketForegroundService.startServiceForMediaProjection(this, object : WebSocketForegroundService.Companion.ServiceReadyCallback {
override fun onServiceReady() {
Log.d(TAG, "服务已准备就绪,开始请求权限")
// 服务启动后,请求权限
runOnUiThread {
val mainActivity = this@MainActivity
try {
val mediaProjectionManager = mainActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
val captureIntent = mediaProjectionManager.createScreenCaptureIntent()
Log.d(TAG, "创建了屏幕捕获意图,准备启动权限请求对话框")
mainActivity.mediaProjectionLauncher.launch(captureIntent)
Log.d(TAG, "权限请求对话框已启动")
} catch (e: Exception) {
Log.e(TAG, "创建屏幕捕获意图失败: ${e.message}", e)
Toast.makeText(mainActivity, "无法请求截图权限: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
})
} catch (e: Exception) {
Log.e(TAG, "启动截图服务失败: ${e.message}", e)
runOnUiThread {
Toast.makeText(this@MainActivity, "截图失败: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
override fun onServiceReady() {
Log.d(TAG, "前台服务已准备就绪,请求屏幕捕获权限")
requestScreenshotPermission()
}
// 请求截图权限的方法
private fun requestScreenshotPermission() {
try {
// 检查是否有MediaProjection权限
val mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
val captureIntent = mediaProjectionManager.createScreenCaptureIntent()
mediaProjectionLauncher.launch(captureIntent)
} catch (e: Exception) {
Log.e(TAG, "请求截图权限失败", e)
runOnUiThread {
Toast.makeText(this, "请求截图权限失败", Toast.LENGTH_SHORT).show()
}
}
}
/**
* 发送截图数据到服务端
*/
fun sendScreenshotData(data: ByteArray) {
try {
// 检查WebSocket客户端是否连接
if (webSocketClient != null && isConnected) {
// 直接发送二进制数据
val byteString = ByteString.of(*data)
val sendResult = webSocketClient?.send(byteString)
Log.d(TAG, "发送二进制截图数据结果: $sendResult")
Log.d(TAG, "发送的二进制数据大小: ${data.size} 字节")
} else {
Log.e(TAG, "WebSocket未连接无法发送截图数据")
}
} catch (e: Exception) {
Log.e(TAG, "发送截图数据异常: ${e.message}", e)
}
}
private fun setupConnectButton() {
connectButton.setOnClickListener {
if (isConnected) {
// 断开连接
disconnect()
} else {
// 建立连接
connect()
}
}
}
/**
* 设置设置按钮的点击事件
*/
private fun setupSettingsButton() {
settingsButton.setOnClickListener {
// 启动设置页面
val intent = Intent(this, SettingsActivity::class.java)
startActivity(intent)
}
}
/**
* 尝试主动检查WebSocket的连接状态
* 这是一个辅助方法,用于在状态回调可能未被触发的情况下检查连接状态
*/
// 检查WebSocket连接状态
private fun checkWebSocketConnectionState(): Boolean {
try {
// 先检查客户端实例是否存在
if (webSocketClient == null) {
Log.d(TAG, "WebSocket client is null")
return false
}
// 获取当前连接状态
val actualConnectedState = webSocketClient!!.connectionState.value == WebSocketClient.ConnectionState.Connected
Log.d(TAG, "WebSocket connection state: $actualConnectedState")
// 更新类变量isConnected
this.isConnected = actualConnectedState
// 更新UI显示的连接状态
runOnUiThread {
updateConnectionStatus(actualConnectedState)
}
return actualConnectedState
} catch (e: Exception) {
Log.e(TAG, "Error checking WebSocket connection state", e)
runOnUiThread {
updateConnectionStatus(false)
}
return false
}
}
/**
* 连接到WebSocket服务器
*/
fun connect(): Boolean {
// 检查webSocketClient实例是否存在
if (webSocketClient == null) {
Log.e(TAG, "WebSocket client is not initialized")
return false
}
try {
// 检查当前连接状态,如果已经连接则先断开
if (webSocketClient!!.connectionState.value == WebSocketClient.ConnectionState.Connected) {
Log.d(TAG, "WebSocket is already connected, disconnecting first")
webSocketClient!!.disconnect()
}
// 连接到WebSocket服务器
webSocketClient!!.connect()
Log.d(TAG, "Attempting to connect to WebSocket server")
// 不立即更新UI为已连接状态等待实际连接结果
// UI更新将由连接状态回调处理
return true
} catch (e: Exception) {
Log.e(TAG, "Error connecting to WebSocket server", e)
runOnUiThread {
updateConnectionStatus(false)
}
return false
}
}
/**
* 断开WebSocket连接
*/
fun disconnect() {
try {
if (webSocketClient != null && webSocketClient!!.connectionState.value == WebSocketClient.ConnectionState.Connected) {
webSocketClient!!.disconnect()
Log.d(TAG, "WebSocket disconnected")
}
} catch (e: Exception) {
Log.e(TAG, "Error disconnecting WebSocket", e)
}
}
/**
* 重新连接WebSocket
*/
private fun reconnectWebSocket() {
try {
// 标记重连中状态
isReconnecting.set(true)
// 断开现有连接
disconnect()
// 延迟一段时间后重新连接
Handler(Looper.getMainLooper()).postDelayed({
try {
Log.d(TAG, "Attempting to reconnect WebSocket")
connect()
} catch (e: Exception) {
Log.e(TAG, "Reconnection failed", e)
} finally {
isReconnecting.set(false)
}
}, RECONNECT_DELAY_MS)
} catch (e: Exception) {
Log.e(TAG, "Error during reconnection", e)
isReconnecting.set(false)
}
}
// 更新连接状态显示
private fun updateConnectionStatus(isConnected: Boolean) {
try {
if (!isFinishing) {
runOnUiThread {
try {
// 更新连接状态文本和图标
connectionStatusText.text = if (isConnected) "已连接" else "未连接"
connectionStatusText.setTextColor(
if (isConnected) android.graphics.Color.GREEN else android.graphics.Color.RED
)
// 更新连接按钮状态
connectButton.isEnabled = (!isConnected) && (!isReconnecting.get())
// 更新连接状态指示器
connectionStatusIndicator.setBackgroundResource(
if (isConnected) R.drawable.connection_status_circle_connected else R.drawable.connection_status_circle
)
} catch (e: Exception) {
Log.e(TAG, "Error updating UI in updateConnectionStatus", e)
}
}
}
} catch (e: Exception) {
Log.e(TAG, "Error in updateConnectionStatus", e)
}
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause()被调用,应用进入后台")
// 如果WebSocket连接已建立启动前台服务以保持连接
if (isConnected) {
Log.d(TAG, "WebSocket已连接启动前台服务")
WebSocketForegroundService.startService(this)
}
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop()被调用")
// 双重检查如果WebSocket连接已建立但前台服务未启动这里再启动一次
if (isConnected) {
Log.d(TAG, "onStop(): WebSocket已连接确认前台服务状态")
}
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy()被调用,释放资源")
// 停止前台服务
WebSocketForegroundService.stopService(this)
// 确保在Activity销毁时释放WebSocket资源
webSocketClient?.release()
webSocketClient = null
// 注销截图数据广播接收器
unregisterScreenshotBroadcastReceiver()
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume()被调用检查URL配置是否变更")
// 重新从SharedPreferences获取配置的WebSocket URL
val sharedPreferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this)
val defaultUrl = getString(R.string.web_socket_url)
val newWebSocketUrl = sharedPreferences.getString(getString(R.string.pref_key_web_socket_url), defaultUrl) ?: defaultUrl
// 比较URL是否发生了变化
if (newWebSocketUrl != webSocketUrl) {
Log.d(TAG, "检测到WebSocket URL发生变化: 旧URL='$webSocketUrl', 新URL='$newWebSocketUrl'")
// 更新URL
webSocketUrl = newWebSocketUrl
// 保存当前连接状态
val wasConnected = isConnected
// 断开现有连接并释放资源
webSocketClient?.release()
webSocketClient = null
// 重新初始化WebSocket客户端
initWebSocketClient()
// 如果之前是连接状态尝试使用新URL重新连接
if (wasConnected) {
Log.d(TAG, "尝试使用新URL重新连接WebSocket")
connect()
}
}
}
}

View File

@@ -0,0 +1,75 @@
package com.joyd.autobot
import android.content.SharedPreferences
import android.os.Bundle
import android.preference.PreferenceManager
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
class SettingsActivity : AppCompatActivity() {
private lateinit var sharedPreferences: SharedPreferences
private lateinit var webSocketUrlEditText: EditText
private lateinit var saveButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
// 初始化Preferences
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
// 绑定UI组件
webSocketUrlEditText = findViewById(R.id.web_socket_url_edit_text)
saveButton = findViewById(R.id.save_settings_btn)
// 加载保存的设置
loadSavedSettings()
// 设置保存按钮的点击事件
saveButton.setOnClickListener {
saveSettings()
}
}
private fun loadSavedSettings() {
// 加载保存的WebSocket地址如果没有保存则使用默认地址
val defaultUrl = "ws://192.168.2.236:8805"
val webSocketUrl = sharedPreferences.getString(getString(R.string.pref_key_web_socket_url), defaultUrl)
webSocketUrlEditText.setText(webSocketUrl)
}
private fun saveSettings() {
// 获取用户输入的WebSocket地址
val webSocketUrl = webSocketUrlEditText.text.toString().trim()
// 简单验证URL格式
if (webSocketUrl.isEmpty() || !isValidWebSocketUrl(webSocketUrl)) {
Toast.makeText(this, "请输入有效的WebSocket地址", Toast.LENGTH_SHORT).show()
return
}
// 保存设置
with(sharedPreferences.edit()) {
putString(getString(R.string.pref_key_web_socket_url), webSocketUrl)
apply()
}
Log.d("SettingsActivity", "保存WebSocket地址: $webSocketUrl")
Toast.makeText(this, "设置已保存", Toast.LENGTH_SHORT).show()
// 设置结果码为OK
setResult(RESULT_OK)
// 关闭Activity
finish()
}
private fun isValidWebSocketUrl(url: String): Boolean {
// 简单的WebSocket URL验证逻辑
return url.startsWith("ws://") || url.startsWith("wss://")
}
}

View File

@@ -0,0 +1,569 @@
package com.joyd.autobot
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.hardware.display.DisplayManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PixelFormat
import android.hardware.display.VirtualDisplay
import android.media.Image
import android.media.ImageReader
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.util.Log
import androidx.core.app.NotificationCompat
import kotlin.math.max
import java.lang.ref.WeakReference
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
class WebSocketForegroundService : Service() {
// 修复TAG常量定义
private val TAG = "WebSocketForegroundService"
companion object {
const val CHANNEL_ID = "WebSocketServiceChannel"
const val NOTIFICATION_ID = 1001
const val ACTION_START = "com.joyd.autobot.action.START"
const val ACTION_STOP = "com.joyd.autobot.action.STOP"
const val IMAGE_READER_FORMAT = android.graphics.PixelFormat.RGBA_8888
const val IMAGE_READER_MAX_IMAGES = 2
const val VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
// 用于存储服务启动回调的静态变量
private var serviceReadyCallback: ServiceReadyCallback? = null
// 服务实例引用
private var instance: WeakReference<WebSocketForegroundService>? = null
// 清理服务实例引用的方法
fun clearInstance() {
instance?.clear()
instance = null
}
// 静态方法设置MediaProjection实例
fun setMediaProjection(context: Context, resultCode: Int, resultData: Intent) {
val service = instance?.get()
if (service != null) {
service.setMediaProjection(resultCode, resultData)
}
}
// 静态方法检查是否有活跃的MediaProjection实例
fun hasActiveMediaProjection(): Boolean {
val service = instance?.get()
return service != null && service.mediaProjection != null
}
// 静态方法:启动服务
fun startService(context: Context) {
val intent = Intent(context, WebSocketForegroundService::class.java)
intent.action = ACTION_START
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent)
} else {
context.startService(intent)
}
}
// 静态方法:停止服务
fun stopService(context: Context) {
val intent = Intent(context, WebSocketForegroundService::class.java)
intent.action = ACTION_STOP
context.stopService(intent)
}
// 获取服务实例的方法
fun getInstance(): WebSocketForegroundService? {
return instance?.get()
}
// 静态方法:启动服务并设置回调
fun startServiceForMediaProjection(context: Context, callback: ServiceReadyCallback) {
// 设置回调
serviceReadyCallback = callback
// 启动服务
val intent = Intent(context, WebSocketForegroundService::class.java)
intent.action = ACTION_START
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent)
} else {
context.startService(intent)
}
}
// 定义服务准备就绪回调接口
interface ServiceReadyCallback {
fun onServiceReady()
}
}
// WebSocket客户端实例 - 类型为Any因为无法确定具体类型
private var webSocketClient: Any? = null
// MediaProjection相关变量
private var mediaProjection: MediaProjection? = null
private var virtualDisplay: VirtualDisplay? = null
private var imageReader: ImageReader? = null
// 截图请求队列
private val screenshotRequestQueue = java.util.concurrent.ConcurrentLinkedQueue<() -> Unit>()
// 用于表示截图请求正在处理中的标志
private val isProcessingScreenshot = AtomicBoolean(false)
// 用于处理截图队列的Handler
private var screenshotHandler: Handler? = null
// 截图请求处理Runnable
private val screenshotRunnable = object : Runnable {
override fun run() {
try {
// 检查是否正在处理截图
if (isProcessingScreenshot.get()) {
// 如果正在处理,稍后再检查
screenshotHandler?.postDelayed(this, 100)
return
}
// 尝试从队列中获取截图请求
val request = screenshotRequestQueue.poll()
if (request != null) {
// 标记为正在处理
isProcessingScreenshot.set(true)
try {
// 执行截图请求
request.invoke()
} catch (e: Exception) {
Log.e(TAG, "Error executing screenshot request", e)
} finally {
// 标记为处理完成
isProcessingScreenshot.set(false)
}
}
} catch (e: Exception) {
Log.e(TAG, "Error in screenshot runnable", e)
} finally {
// 如果队列不为空,继续处理
if (!screenshotRequestQueue.isEmpty()) {
screenshotHandler?.postDelayed(this, 100)
}
}
}
}
// 设置MediaProjection实例的方法
private fun setMediaProjection(resultCode: Int, resultData: Intent) {
try {
val mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
val newMediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData)
// 释放旧的MediaProjection
releaseMediaProjection()
// 设置新的MediaProjection
mediaProjection = newMediaProjection
// 设置回调当MediaProjection被系统终止时收到通知
mediaProjection?.registerCallback(object : MediaProjection.Callback() {
override fun onStop() {
Log.d(TAG, "MediaProjection stopped")
// 发送广播通知MainActivity需要重新请求权限
sendMediaProjectionPermissionRequiredBroadcast()
}
}, null)
Log.d(TAG, "MediaProjection set successfully")
} catch (e: Exception) {
Log.e(TAG, "Error setting MediaProjection", e)
}
}
// 发送MediaProjection权限请求广播
private fun sendMediaProjectionPermissionRequiredBroadcast() {
try {
val intent = Intent("com.joyd.autobot.MEDIA_PROJECTION_PERMISSION_REQUIRED")
intent.setPackage(packageName) // 指定包名解决UnsafeImplicitIntentLaunch错误
sendBroadcast(intent)
Log.d(TAG, "Sent MEDIA_PROJECTION_PERMISSION_REQUIRED broadcast")
} catch (e: Exception) {
Log.e(TAG, "Error sending broadcast", e)
}
}
// 释放MediaProjection资源
private fun releaseMediaProjection() {
try {
if (virtualDisplay != null) {
virtualDisplay?.release()
virtualDisplay = null
}
if (imageReader != null) {
imageReader?.close()
imageReader = null
}
if (mediaProjection != null) {
mediaProjection?.stop()
mediaProjection = null
}
} catch (e: Exception) {
Log.w(TAG, "Error stopping MediaProjection", e)
} finally {
mediaProjection = null
}
}
// 创建通知渠道Android O及以上版本需要
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
"WebSocket服务",
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = "保持WebSocket连接活跃"
channel.enableVibration(false)
channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}
}
// 创建前台服务通知
private fun createForegroundNotification(): Notification {
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("WebSocket服务")
.setContentText("保持WebSocket连接活跃")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setOngoing(true)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CHANNEL_ID)
}
return builder.build()
}
// 安全地重建MediaProjection实例
private fun recreateMediaProjection(): Boolean {
try {
// 释放旧的MediaProjection
releaseMediaProjection()
// 创建新的MediaProjection但这需要用户授权所以这里只是清理工作
// 实际的MediaProjection创建需要通过MainActivity请求权限
Log.d(TAG, "MediaProjection has been cleared, ready for recreation")
// 发送广播通知MainActivity需要重新请求权限
sendMediaProjectionPermissionRequiredBroadcast()
return true
} catch (e: Exception) {
Log.e(TAG, "Error recreating MediaProjection", e)
return false
}
}
// 安全检查方法
private fun performSecurityChecks(): Boolean {
// 这里可以添加一些安全检查逻辑
// 例如检查应用是否在前台,是否有权限等
return true
}
// 安全地请求截图
fun requestScreenshotSafely() {
try {
// 先进行安全检查
if (!performSecurityChecks()) {
Log.w(TAG, "Security checks failed, cannot perform screenshot")
return
}
// 检查MediaProjection是否有效
if (mediaProjection == null) {
Log.w(TAG, "MediaProjection is null, cannot perform screenshot")
// 尝试重新创建MediaProjection
if (!recreateMediaProjection()) {
return
}
// 由于重新创建MediaProjection需要用户授权这里不能立即执行截图
return
}
// 将截图请求添加到队列
screenshotRequestQueue.add {
// 执行实际的截图操作
takeScreenshot()
}
// 确保Handler已初始化
if (screenshotHandler == null) {
screenshotHandler = Handler(Looper.getMainLooper())
}
// 启动截图队列处理
screenshotHandler?.removeCallbacks(screenshotRunnable)
screenshotHandler?.post(screenshotRunnable)
} catch (e: Exception) {
Log.e(TAG, "Error in requestScreenshotSafely", e)
}
}
// 执行实际的截图操作
private fun takeScreenshot() {
try {
Log.d(TAG, "Starting screenshot process")
// 获取屏幕参数
val metrics = resources.displayMetrics
val screenWidth = metrics.widthPixels
val screenHeight = metrics.heightPixels
val screenDensity = metrics.densityDpi
Log.d(TAG, "Screen parameters: $screenWidth x $screenHeight, density: $screenDensity")
// 创建ImageReader
imageReader = ImageReader.newInstance(screenWidth, screenHeight, IMAGE_READER_FORMAT, IMAGE_READER_MAX_IMAGES)
// 创建VirtualDisplay
virtualDisplay = mediaProjection?.createVirtualDisplay(
"ScreenshotDisplay",
screenWidth,
screenHeight,
screenDensity,
VIRTUAL_DISPLAY_FLAGS,
imageReader?.surface,
null,
null
)
if (virtualDisplay == null) {
Log.e(TAG, "Failed to create VirtualDisplay")
return
}
Log.d(TAG, "VirtualDisplay created successfully")
// 设置ImageReader的回调
val imageAvailableListener = ImageReader.OnImageAvailableListener { reader ->
try {
// 获取Image对象
val image = reader.acquireLatestImage()
if (image == null) {
Log.e(TAG, "Failed to acquire image")
return@OnImageAvailableListener
}
try {
// 处理Image对象
val bitmap = imageToBitmap(image)
if (bitmap != null) {
// 将Bitmap转换为字节数组
val screenshotData = bitmapToByteArray(bitmap)
if (screenshotData != null) {
// 发送截图数据广播
sendScreenshotDataBroadcast(screenshotData)
} else {
Log.e(TAG, "Failed to convert bitmap to byte array")
}
} else {
Log.e(TAG, "Failed to convert image to bitmap")
}
} finally {
// 释放Image对象
image.close()
// 释放VirtualDisplay
if (virtualDisplay != null) {
virtualDisplay?.release()
virtualDisplay = null
}
// 关闭ImageReader
if (imageReader != null) {
imageReader?.close()
imageReader = null
}
}
} catch (e: Exception) {
Log.e(TAG, "Error in imageAvailableListener", e)
}
}
imageReader?.setOnImageAvailableListener(imageAvailableListener, null)
// 添加延迟确保VirtualDisplay已经稳定
Thread.sleep(100)
} catch (e: Exception) {
Log.e(TAG, "Error taking screenshot", e)
// 清理资源
try {
if (virtualDisplay != null) {
virtualDisplay?.release()
virtualDisplay = null
}
if (imageReader != null) {
imageReader?.close()
imageReader = null
}
} catch (cleanupException: Exception) {
Log.e(TAG, "Error during resource cleanup", cleanupException)
}
}
}
// 将Image对象转换为Bitmap
private fun imageToBitmap(image: Image): Bitmap? {
try {
// 获取Image的平面
val planes = image.planes
val buffer = planes[0].buffer
val pixelStride = planes[0].pixelStride
val rowStride = planes[0].rowStride
val rowPadding = rowStride - pixelStride * image.width
// 创建Bitmap
val bitmap = Bitmap.createBitmap(
image.width + rowPadding / pixelStride,
image.height,
Bitmap.Config.ARGB_8888
)
bitmap.copyPixelsFromBuffer(buffer)
// 裁剪Bitmap以移除额外的行填充
return Bitmap.createBitmap(bitmap, 0, 0, image.width, image.height)
} catch (e: Exception) {
Log.e(TAG, "Error converting image to bitmap", e)
return null
}
}
// 将Bitmap转换为字节数组
private fun bitmapToByteArray(bitmap: Bitmap?): ByteArray? {
if (bitmap == null) {
Log.e(TAG, "bitmapToByteArray: bitmap is null")
return null
}
try {
val outputStream = java.io.ByteArrayOutputStream()
// 使用JPEG格式替代PNG提高兼容性和转换成功率
val compressResult = bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
val byteArray = outputStream.toByteArray()
outputStream.close()
// 验证压缩结果和字节数组是否有效
if (!compressResult || byteArray.isEmpty()) {
Log.e(TAG, "bitmapToByteArray: compression failed or result is empty")
return null
}
Log.d(TAG, "bitmapToByteArray: conversion successful, size: ${byteArray.size} bytes")
return byteArray
} catch (e: Exception) {
Log.e(TAG, "Error converting bitmap to byte array", e)
return null
}
}
// 发送截图数据广播
private fun sendScreenshotDataBroadcast(data: ByteArray) {
try {
val intent = Intent("com.joyd.autobot.SCREENSHOT_DATA")
intent.putExtra("screenshot_data", data)
intent.setPackage(packageName) // 指定包名解决UnsafeImplicitIntentLaunch错误
sendBroadcast(intent)
Log.d(TAG, "Sent screenshot data broadcast, size: ${data.size} bytes")
} catch (e: Exception) {
Log.e(TAG, "Error sending screenshot data broadcast", e)
}
}
// 获取当前的MainActivity实例
// 注意此方法目前返回null因为我们已经移除了对MainActivity私有属性的直接访问
private fun getCurrentMainActivity(): Activity? {
try {
// 在现代Android版本中getRunningTasks已被弃用且不可用
// 因此此方法简化为直接返回null
Log.d(TAG, "MainActivity instance is not available through this method")
} catch (e: Exception) {
Log.e(TAG, "Error getting MainActivity", e)
}
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand() called with action: ${intent?.action}")
// 初始化服务实例引用
instance = WeakReference(this)
// 处理不同的动作
when (intent?.action) {
ACTION_START -> {
// 启动前台服务
createNotificationChannel()
val notification = createForegroundNotification()
startForeground(NOTIFICATION_ID, notification)
// 如果有回调设置,通知服务已准备就绪
if (serviceReadyCallback != null) {
serviceReadyCallback?.onServiceReady()
serviceReadyCallback = null // 只回调一次
}
Log.d(TAG, "WebSocket foreground service started")
}
ACTION_STOP -> {
// 停止前台服务
stopForeground(true)
stopSelf()
Log.d(TAG, "WebSocket foreground service stopped")
}
else -> {
Log.w(TAG, "Unknown action received: ${intent?.action}")
}
}
// 如果服务被终止,不自动重启
return START_NOT_STICKY
}
override fun onDestroy() {
super.onDestroy()
// 清理资源
releaseMediaProjection()
// 注意这里不调用webSocketClient的close方法因为无法确定其具体类型
WebSocketForegroundService.clearInstance()
Log.d(TAG, "Service destroyed")
}
override fun onBind(intent: Intent?): IBinder? {
// 不支持绑定
return null
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/errorColor" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/successColor" />
</shape>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true">
<shape android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="#FFFFFF" />
<stroke
android:width="2dp"
android:color="@color/primaryColor" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="#FFFFFF" />
<stroke
android:width="1dp"
android:color="#CCCCCC" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,51 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<!-- 主背景 -->
<path
android:fillColor="#1976D2"
android:pathData="M0,0h108v108h-108z" />
<!-- 装饰性网格线 - 科技感 -->
<path
android:fillColor="#00000000"
android:pathData="M0,36h108M0,72h108M36,0v108M72,0v108"
android:strokeWidth="0.5"
android:strokeColor="#33FFFFFF" />
<!-- 中心发光效果 -->
<path
android:pathData="M54,54m-30,0a30,30 0 1,0 60,0a30,30 0 1,0 -60,0">
<aapt:attr name="android:fillColor">
<radialGradient
android:centerX="54"
android:centerY="54"
android:gradientRadius="30"
android:type="radial">
<item
android:color="#20FFFFFF"
android:offset="0.0" />
<item
android:color="#00FFFFFF"
android:offset="1.0" />
</radialGradient>
</aapt:attr>
</path>
<!-- 装饰性圆点 -->
<path
android:fillColor="#20FFFFFF"
android:pathData="M18,18m-2,0a2,2 0 1,1 4,0a2,2 0 1,1 -4,0" />
<path
android:fillColor="#20FFFFFF"
android:pathData="M90,18m-2,0a2,2 0 1,1 4,0a2,2 0 1,1 -4,0" />
<path
android:fillColor="#20FFFFFF"
android:pathData="M18,90m-2,0a2,2 0 1,1 4,0a2,2 0 1,1 -4,0" />
<path
android:fillColor="#20FFFFFF"
android:pathData="M90,90m-2,0a2,2 0 1,1 4,0a2,2 0 1,1 -4,0" />
</vector>

View File

@@ -0,0 +1,70 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<!-- 阴影效果 -->
<path android:pathData="M28,70l52,0l0,38l-52,0z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="60"
android:endY="100"
android:startX="60"
android:startY="70"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<!-- 机器人头部 -->
<path
android:fillColor="#2196F3"
android:pathData="M30,30h48v32c0,2.2 -1.8,4 -4,4H34c-2.2,0 -4,-1.8 -4,-4v-32z" />
<!-- 天线 -->
<path
android:fillColor="#2196F3"
android:pathData="M42,22h4v8h-4zM62,22h4v8h-4z" />
<!-- 眼睛 -->
<path
android:fillColor="#FFFFFF"
android:pathData="M40,40h8v8h-8zM60,40h8v8h-8z" />
<!-- 机器人身体 -->
<path
android:fillColor="#1976D2"
android:pathData="M34,66h40c1.1,0 2,0.9 2,2v28c0,1.1 -0.9,2 -2,2H34c-1.1,0 -2,-0.9 -2,-2v-28c0,-1.1 0.9,-2 2,-2z" />
<!-- 自动化符号 - 循环箭头 -->
<path
android:fillColor="#FFFFFF"
android:pathData="M48,78c-2.2,0 -4,1.8 -4,4s1.8,4 4,4s4,-1.8 4,-4s-1.8,-4 -4,-4zM72,78c-2.2,0 -4,1.8 -4,4s1.8,4 4,4s4,-1.8 4,-4s-1.8,-4 -4,-4z" />
<path
android:strokeColor="#FFFFFF"
android:strokeWidth="2"
android:strokeLineCap="round"
android:pathData="M52,82l8,0M72,82l-8,0" />
<path
android:strokeColor="#FFFFFF"
android:strokeWidth="2"
android:strokeLineCap="round"
android:pathData="M56,78v-8c0,-2.2 1.8,-4 4,-4s4,1.8 4,4v4" />
<path
android:strokeColor="#FFFFFF"
android:strokeWidth="2"
android:strokeLineCap="round"
android:pathData="M64,82v4c0,2.2 -1.8,4 -4,4s-4,-1.8 -4,-4v-8" />
<!-- 底部装饰 -->
<path
android:fillColor="#0D47A1"
android:pathData="M34,96h40v4h-40z" />
</vector>

View File

@@ -0,0 +1,37 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<!-- 单色机器人图标 - 简化版本 -->
<path
android:fillColor="#FFFFFF"
android:pathData="M30,30h48v32c0,2.2 -1.8,4 -4,4H34c-2.2,0 -4,-1.8 -4,-4v-32z" />
<!-- 天线 -->
<path
android:fillColor="#FFFFFF"
android:pathData="M42,22h4v8h-4zM62,22h4v8h-4z" />
<!-- 眼睛 -->
<path
android:fillColor="#000000"
android:pathData="M42,42h4v4h-4zM62,42h4v4h-4z" />
<!-- 机器人身体 -->
<path
android:fillColor="#FFFFFF"
android:pathData="M34,66h40c1.1,0 2,0.9 2,2v28c0,1.1 -0.9,2 -2,2H34c-1.1,0 -2,-0.9 -2,-2v-28c0,-1.1 0.9,-2 2,-2z" />
<!-- 简化的自动化符号 -->
<path
android:fillColor="#000000"
android:pathData="M48,78c-2.2,0 -4,1.8 -4,4s1.8,4 4,4s4,-1.8 4,-4s-1.8,-4 -4,-4zM72,78c-2.2,0 -4,1.8 -4,4s1.8,4 4,4s4,-1.8 4,-4s-1.8,-4 -4,-4z" />
<!-- 连接线条 -->
<path
android:strokeColor="#000000"
android:strokeWidth="2"
android:strokeLineCap="round"
android:pathData="M56,78v-4M64,82v4" />
</vector>

View File

@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_material_light"
tools:context=".MainActivity">
<!-- 顶部标题区域 -->
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/app_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="智动助手"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="@color/primary_text_default_material_light" />
<TextView
android:id="@+id/app_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="安卓自动化脚本工具"
android:textSize="16sp"
android:textColor="@color/secondary_text_default_material_light"
android:layout_marginTop="8dp" />
</LinearLayout>
<!-- 连接状态区域 -->
<LinearLayout
android:id="@+id/connection_status_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center_vertical"
android:background="@color/cardBackgroundColor"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:elevation="2dp"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintBottom_toTopOf="@id/feature_cards">
<View
android:id="@+id/connection_status_indicator"
android:layout_width="16dp"
android:layout_height="16dp"
android:background="@drawable/connection_status_circle" />
<TextView
android:id="@+id/connection_status_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="连接状态: 未连接"
android:textSize="16sp"
android:textColor="@color/textPrimary"
android:layout_marginLeft="12dp" />
<Button
android:id="@+id/connect_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="连接"
android:textAllCaps="false"
android:backgroundTint="@color/primaryColor" />
</LinearLayout>
<!-- 功能卡片区域 -->
<LinearLayout
android:id="@+id/feature_cards"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
android:gravity="center"
app:layout_constraintTop_toBottomOf="@id/connection_status_area"
app:layout_constraintBottom_toTopOf="@id/action_buttons">
<androidx.cardview.widget.CardView
android:id="@+id/script_list_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:elevation="4dp"
app:cardBackgroundColor="@color/cardview_light_background"
app:cardCornerRadius="12dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="脚本列表"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/primary_text_default_material_light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="管理和运行您的自动化脚本"
android:textSize="14sp"
android:textColor="@color/secondary_text_default_material_light"
android:layout_marginTop="4dp" />
<Button
android:id="@+id/manage_scripts_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="管理脚本"
android:layout_marginTop="16dp"
android:textAllCaps="false"
android:backgroundTint="@color/colorAccent" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/quick_actions_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp"
app:cardBackgroundColor="@color/cardview_light_background"
app:cardCornerRadius="12dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="快捷操作"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/primary_text_default_material_light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="快速启动常用功能"
android:textSize="14sp"
android:textColor="@color/secondary_text_default_material_light"
android:layout_marginTop="4dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:layout_marginTop="16dp">
<Button
android:id="@+id/start_recording_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="录制脚本"
android:layout_marginRight="8dp"
android:textAllCaps="false" />
<Button
android:id="@+id/run_last_script_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="运行上次脚本"
android:layout_marginLeft="8dp"
android:textAllCaps="false" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
<!-- 底部操作按钮 -->
<LinearLayout
android:id="@+id/action_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent">
<Button
android:id="@+id/settings_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置"
android:textAllCaps="false"
android:layout_marginRight="16dp" />
<Button
android:id="@+id/about_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="关于"
android:textAllCaps="false" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_material_light"
tools:context=".SettingsActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="@color/primary_text_default_material_light"
android:layout_marginBottom="24dp" />
<!-- WebSocket地址设置 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="WebSocket地址"
android:textSize="16sp"
android:textColor="@color/primary_text_default_material_light"
android:layout_marginBottom="8dp" />
<EditText
android:id="@+id/web_socket_url_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:hint="ws://192.168.2.236:8805"
android:textSize="16sp"
android:padding="12dp"
android:background="@drawable/edit_text_background"
android:layout_marginBottom="8dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="示例: ws://192.168.2.236:8805"
android:textSize="12sp"
android:textColor="@color/secondary_text_default_material_light" />
</LinearLayout>
<!-- 保存按钮 -->
<Button
android:id="@+id/save_settings_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="保存"
android:textSize="16sp"
android:padding="12dp"
android:textAllCaps="false"
android:backgroundTint="@color/primaryColor" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
</adaptive-icon>

View File

@@ -0,0 +1,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.AutoBot" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your dark theme here. -->
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
</style>
</resources>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="primaryColor">#1E88E5</color>
<color name="primaryDarkColor">#1565C0</color>
<color name="secondaryColor">#FFC107</color>
<color name="colorAccent">#FF4081</color>
<color name="successColor">#4CAF50</color>
<color name="warningColor">#FF9800</color>
<color name="errorColor">#F44336</color>
<color name="textPrimary">#212121</color>
<color name="textSecondary">#757575</color>
<color name="backgroundColor">#F5F5F5</color>
<color name="cardBackgroundColor">#FFFFFF</color>
</resources>

View File

@@ -0,0 +1,9 @@
<resources>
<string name="app_name">智动助手</string>
<string name="pref_key_web_socket_url">web_socket_url</string>
<string name="web_socket_url">ws://localhost:8080/ws</string>
<string name="connect">连接</string>
<string name="disconnect">断开</string>
<string name="status_connected">已连接</string>
<string name="status_disconnected">未连接</string>
</resources>

View File

@@ -0,0 +1,9 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.AutoBot" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
<style name="Theme.AutoBot" parent="Base.Theme.AutoBot" />
</resources>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older than API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

View File

@@ -0,0 +1,19 @@
<?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.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">192.168.2.236</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>

View File

@@ -0,0 +1,17 @@
package com.joyd.autobot
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -0,0 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
}

View File

@@ -0,0 +1,23 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true

View File

@@ -0,0 +1,35 @@
[versions]
agp = "8.13.0"
kotlin = "2.0.21"
coreKtx = "1.10.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
appcompat = "1.6.1"
material = "1.10.0"
activity = "1.8.0"
constraintlayout = "2.1.4"
cardview = "1.0.0"
preference = "1.2.1"
websocketclientVersion = "1.0.4"
okhttpVersion = "4.12.0"
[libraries]
androidx-preference = { group = "androidx.preference", name = "preference", version.ref = "preference" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
androidx-cardview = { group = "androidx.cardview", name = "cardview", version.ref = "cardview" }
websocketclient = { group = "com.joyd.joydlib.io", name = "websocketclient", version.ref = "websocketclientVersion" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttpVersion" }
joydlibdev = { group = "com.joyd", name = "joydlibdev", version = "1.0.0" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

Binary file not shown.

View File

@@ -0,0 +1,10 @@
#Wed Aug 27 16:52:22 CST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
#distributionUrl=file\:/E:/Download/AutoBot/Libs/gradle-8.13-bin.zip
#distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
#distributionUrl=https\://mirrors.tencent.com/gradle/gradle-8.13-bin.zip
#distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
distributionUrl=http\://geek.cdjkt.com:30003/repository/gradle/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
AutoRobot/Android/Robot/gradlew vendored Normal file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
AutoRobot/Android/Robot/gradlew.bat vendored Normal file
View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -0,0 +1,41 @@
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
maven {
url = uri("http://geek.cdjkt.com:30003/repository/maven-public")
isAllowInsecureProtocol = true
}
maven {
url = uri("http://geek.cdjkt.com:30003/repository/maven-releases")
isAllowInsecureProtocol = true
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven {
url = uri("http://geek.cdjkt.com:30003/repository/maven-public")
isAllowInsecureProtocol = true
}
maven {
url = uri("http://geek.cdjkt.com:30003/repository/maven-releases")
isAllowInsecureProtocol = true
}
maven { url = uri("https://maven.aliyun.com/repository/public") }
google()
mavenCentral()
// JoydLib库已在上面的私有Maven仓库中提供
}
}
rootProject.name = "AutoBot"
include(":app")