{"id":13621160,"url":"https://github.com/openatx/atx-agent","last_synced_at":"2026-01-14T16:31:51.114Z","repository":{"id":37580278,"uuid":"104067649","full_name":"openatx/atx-agent","owner":"openatx","description":"HTTP Server runs on android devices","archived":true,"fork":false,"pushed_at":"2024-04-07T08:29:32.000Z","size":1703,"stargazers_count":766,"open_issues_count":58,"forks_count":281,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-04-15T01:38:37.700Z","etag":null,"topics":["android","go"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openatx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-19T11:43:17.000Z","updated_at":"2025-04-10T17:34:21.000Z","dependencies_parsed_at":"2024-01-14T05:09:29.439Z","dependency_job_id":"f9f0e308-1e7f-4098-b7e0-b81edec739e3","html_url":"https://github.com/openatx/atx-agent","commit_stats":{"total_commits":154,"total_committers":5,"mean_commits":30.8,"dds":"0.038961038961038974","last_synced_commit":"1fdd3bf999217771ed973a63cf14e1252201e657"},"previous_names":[],"tags_count":63,"template":false,"template_full_name":null,"purl":"pkg:github/openatx/atx-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Fatx-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Fatx-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Fatx-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Fatx-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openatx","download_url":"https://codeload.github.com/openatx/atx-agent/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openatx%2Fatx-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28426011,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T15:24:48.085Z","status":"ssl_error","status_checked_at":"2026-01-14T15:23:41.940Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","go"],"created_at":"2024-08-01T21:01:03.111Z","updated_at":"2026-01-14T16:31:51.099Z","avatar_url":"https://github.com/openatx.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# atx-agent\n[![Build Status](https://travis-ci.org/openatx/atx-agent.svg?branch=master)](https://travis-ci.org/openatx/atx-agent)\n\n这个项目的主要目的是为了屏蔽不同安卓机器的差异，然后开放出统一的HTTP接口供 [openatx/uiautomator2](https://github.com/openatx/uiautomator2)使用。项目最终会发布成一个二进制程序，运行在Android系统的后台。\n\n这个项目是如何屏蔽不同机器的差异的呢？举个例子来说，截图这个操作，大概需要3次判断才行。\n\n1. 先判断minicap是否安装可用，然后minicap截图。毕竟minicap截图速度最快\n2. 使用uiautomator2提供的接口截图。（模拟器除外）\n3. 使用screencap截图，然后根据屏幕的旋转调整旋转方向。(一般只有模拟器用这种方式截图)\n\n正是Android手机不同的表现形式，才导致了需要这么多的判断。而atx-agent就是为了将这些操作帮你处理了。然后提供统一的HTTP接口(GET /screenshot)供你使用。\n\n# Develop\n这个项目是用Go语言写成的。编译的时候的需要你有一点Go语言的基础。\n更多内容查看 [DEVELOP.md](DEVELOP.md)\n\n# Installation\n从\u003chttps://github.com/openatx/atx-agent/releases\u003e下载以`linux_armv7.tar.gz`结尾的二进制包。绝大部分手机都是linux-arm架构的。\n\n解压出`atx-agent`文件，然后打开控制台\n```bash\n$ adb push atx-agent /data/local/tmp\n$ adb shell chmod 755 /data/local/tmp/atx-agent\n# launch atx-agent in daemon mode\n$ adb shell /data/local/tmp/atx-agent server -d\n\n# stop already running atx-agent and start daemon\n$ adb shell /data/local/tmp/atx-agent server -d --stop\n```\n\n默认监听的端口是7912。\n\n# 常用接口\n假设手机的地址是$DEVICE_URL (eg: `http://10.0.0.1:7912`)\n\n## 获取手机截图\n```bash\n# jpeg format image\n$ curl $DEVICE_URL/screenshot\n\n# 使用内置的uiautomator截图\n$ curl \"$DEVICE_URL/screenshot/0?minicap=false\"\n```\n\n## 获取当前程序版本\n```bash\n$ curl $DEVICE_URL/version\n# expect example: 0.0.2\n```\n\n## 获取设备信息\n```bash\n$ curl $DEVICE_URL/info\n{\n    \"udid\": \"bf755cab-ff:ff:ff:ff:ff:ff-SM901\",\n    \"serial\": \"bf755cab\",\n    \"brand\": \"SMARTISAN\",\n    \"model\": \"SM901\",\n    \"hwaddr\": \"ff:ff:ff:ff:ff:ff\",\n    \"agentVersion\": \"dev\"\n}\n```\n\n## 获取Hierarchy\n这个接口目前比较高级，当跟uiautomator通信失败的时候，它会在后台启动uiautomator这个服务，等它恢复正常了，在返回数据。\n\n```bash\n$ curl $DEVICE_URL/dump/hierarchy\n{\n    \"jsonrpc\":\"2.0\",\n    \"id\":1559113464,\n    \"result\": \"\u003c?xml version='1.0\u003e ... hierarchy ...\"\n}\n\n# 停止掉uiautomator\n$ curl -X DELETE $DEVICE_URL/uiautomator\nSuccess\n\n# 再次调用, 依然OK，只是可能要等个7~8s\n$ curl $DEVICE_URL/dump/hierarchy\n{\n    \"jsonrpc\": \"2.0\",\n    ...\n}\n```\n\n## 安装应用\n```bash\n$ curl -X POST -d url=\"http://some-host/some.apk\" $DEVICE_URL/install\n# expect install id\n2\n# get install progress\n$ curl -X GET $DEVICE_URL/install/1\n{\n    \"id\": \"2\",\n    \"titalSize\": 770571,\n    \"copiedSize\": 770571,\n    \"message\": \"success installed\"\n}\n```\n\n## Shell命令\n```bash\n$ curl -X POST -d command=\"pwd\" $DEVICE_URL/shell\n{\n    \"output\": \"/\",\n    \"error\": null\n}\n```\n\n后台Shell命令(可以在后台持续运行，不会被杀掉)\n\n```bash\n$ curl -X POST -d command=\"pwd\" $DEVICE_URL/shell/background\n{\n    \"success\": true,\n}\n```\n\n## Webview相关\n```bash\n$ curl -X GET $DEVICE_URL/webviews\n[\n    \"webview_devtools_remote_m6x_21074\",\n    \"webview_devtools_remote_m6x_27681\",\n    \"chrome_devtools_remote\"\n]\n```\n\n\n## App信息获取\n```bash\n# 获取所有运行的应用\n$ curl $DEVICE_URL/proc/list\n[\n    {\n        \"cmdline\": [\"/system/bin/adbd\", \"--root_seclabel=u:r:su:s0\"],\n        \"name\": \"adbd\",\n        \"pid\": 16177\n    },\n    {\n        \"cmdline\": [\"com.netease.cloudmusic\"],\n        \"name\": \"com.netease.cloudmusic\",\n        \"pid\": 15532\n    }\n]\n\n# 获取应用的内存信息(数据仅供参考)，单位KB，total代表应用的PSS\n$ curl $DEVICE_URL/proc/com.netease.cloudmusic/meminfo\n{\n    \"code\": 17236,\n    \"graphics\": 20740,\n    \"java heap\": 22288,\n    \"native heap\": 20576,\n    \"private other\": 10632,\n    \"stack\": 48,\n    \"system\": 110925,\n    \"total\": 202445,\n    \"total swap pss\": 88534\n}\n\n# 获取应用以及其所有子进程的内存数据\n$ curl $DEVICE_URL/proc/com.netease.cloudmusic/meminfo/all\n{\n    \"com.netease.cloudmusic\": {\n        \"code\": 15952,\n        \"graphics\": 19328,\n        \"java heap\": 45488,\n        \"native heap\": 20840,\n        \"private other\": 4056,\n        \"stack\": 956,\n        \"system\": 18652,\n        \"total\": 125272\n    },\n    \"com.netease.cloudmusic:browser\": {\n        \"code\": 848,\n        \"graphics\": 12,\n        \"java heap\": 6580,\n        \"native heap\": 5428,\n        \"private other\": 1592,\n        \"stack\": 336,\n        \"system\": 10603,\n        \"total\": 25399\n    }\n}\n```\n\n# 获取CPU信息\n\n如果进程是多线程运行的话，且机器是多核的，返回的CPU Percent可能会大于100%\n\n```bash\ncurl $DEVICE_URL/proc/\u003cpackage or pid\u003e/cpuinfo\n# success return\n{\n    \"pid\": 1122,\n    \"user\": 288138,\n    \"system\": 73457,\n    \"percent\": 50.0,\n    \"systemPercent\": 88.372,\n    \"coreCount\": 4,\n}\n# failure return\n410 Gone, Or 500 Internal error\n```\n\n\n## 下载文件\n```bash\n$ curl $DEVICE_URL/raw/sdcard/tmp.txt\n```\n\n## 上传文件\n```bash\n# 上传到/sdcard目录下 (url以/结尾)\n$ curl -F \"file=@somefile.txt\" $DEVICE_URL/upload/sdcard/\n\n# 上传到/sdcard/tmp.txt\n$ curl -F \"file=@somefile.txt\" $DEVICE_URL/upload/sdcard/tmp.txt\n```\n\n上传目录（url必须以/结尾)\n\n```bash\n$ curl -F file=@some.zip -F dir=true $DEVICE_URL/upload/sdcard/\n```\n\n## 获取文件和目录信息\n```bash\n# 文件\n$ curl -X GET $DEVICE_URL/finfo/data/local/tmp/tmp.txt\n{\n\t\"name\": \"tmp.txt\",\n\t\"path\": \"/data/local/tmp/tmp.txt\",\n\t\"isDirectory\": false,\n\t\"size\": 15232,\n}\n\n# 目录\n$ curl -X GET $DEVICE_URL/finfo/data/local/tmp\n{\n\t\"name\": \"tmp\",\n\t\"path\": \"/data/local/tmp\",\n\t\"isDirectory\": true,\n\t\"size\": 8192,\n\t\"files\": [\n\t\t{\n\t\t\t\"name\": \"tmp.txt\", \n\t\t\t\"path\": \"/data/local/tmp/tmp.txt\"\n\t\t\t\"isDirectory\": false,\n\t\t}\n\t]\n}\n```\n\n相当于将`some.zip`上传到手机，然后执行`unzip some.zip -d /sdcard`, 最后将`some.zip`删除\n\n## 离线下载\n```bash\n# 离线下载，返回ID\n$ curl -F url=https://.... -F filepath=/sdcard/some.txt -F mode=0644 $DEVICE_URL/download\n1\n# 通过返回的ID查看下载状态\n$ curl $DEVICE_URL/download/1\n{\n    \"message\": \"downloading\",\n    \"progress\": {\n        \"totalSize\": 15000,\n        \"copiedSize\": 10000\n    }\n}\n```\n\n## uiautomator起停\n```bash\n# 启动\n$ curl -X POST $DEVICE_URL/uiautomator\nSuccess\n\n# 停止\n$ curl -X DELETE $DEVICE_URL/uiautomator\nSuccess\n\n# 再次停止\n$ curl -X DELETE $DEVICE_URL/uiautomator\nAlready stopped\n\n# 获取uiautomator状态\n$ curl $DEVICE/uiautomator\n{\n    \"running\": true\n}\n```\n\n## 启动应用\n```bash\n# timeout 代表 am start -n 的超时时间\n# flags 默认为 -S -W\n$ http POST $DEVICE_URL/session/{com.cleanmaster.mguard_cn} timeout==10s flags==\"-S\"\n{\n    \"mainActivity\": \"com.keniu.security.main.MainActivity\",\n    \"output\": \"Stopping: com.cleanmaster.mguard_cn\\nStarting: Intent { cmp=com.cleanmaster.mguard_cn/com.keniu.security.main.MainActivity }\\n\",\n    \"success\": true\n}\n```\n\n## 获取包信息\n```bash\n$ http GET $DEVICE_URL/packages/{packageName}/info\n{\n    \"success\": true,\n    \"data\": {\n        \"mainActivity\": \"com.github.uiautomator.MainActivity\",\n        \"label\": \"ATX\",\n        \"versionName\": \"1.1.7\",\n        \"versionCode\": 1001007,\n        \"size\":1760809\n    }\n}\n```\n\n其中`size`单位为字节\n\n## 获取包的图标\n```\n$ curl -XGET $DEVICE_URL/packages/{packageName}/icon\n# 返回包的图标文件\n# 失败的情况 status code != 200\n```\n\n## 获取所有包的信息\n该接口速度有点慢，大约需要3s。\n\n原理是通过`pm list packages -3 -f`获取包的信息，然后在用`androidbinary`库对包进行解析\n\n```bash\n$ http GET $DEVICE_URL/packages\n[\n    {\n        \"packageName\": \"com.github.uiautomator\",\n        \"mainActivity\": \"com.github.uiautomator.MainActivity\",\n        \"label\": \"ATX\",\n        \"versionName\": \"1.1.7-2-361182f-dirty\",\n        \"versionCode\": 1001007,\n        \"size\": 1639366\n    },\n    {\n        \"packageName\": \"com.smartisanos.payment\",\n        \"mainActivity\": \"\",\n        \"label\": \"\",\n        \"versionName\": \"1.1\",\n        \"versionCode\": 1,\n        \"size\": 3910826\n    },\n    ...\n]\n```\n\n## 调整uiautomator自动停止时间 （默认3分钟）\n```bash\n$ curl -X POST 10.0.0.1:7912/newCommandTimeout --data 300\n{\n    \"success\": true,\n    \"description\":\"newCommandTimeout updated to 5m0s\"\n}\n```\n\n## 程序自升级(暂时不能用了)\n升级程序从gihub releases里面直接下载，升级完后自动重启\n\n升级到最新版\n\n```bash\n$ curl 10.0.0.1:7912/upgrade\n```\n\n指定升级的版本\n\n```bash\n$ curl \"10.0.0.1:7912/upgrade?version=0.0.2\"\n```\n\n## 修复minicap, minitouch程序\n\n```bash\n# Fix minicap \n$ curl -XPUT 10.0.0.1:7912/minicap\n\n# Fix minitouch\n$ curl -XPUT 10.0.0.1:7912/minitouch\n```\n\n## 视频录制(不推荐用)\n开始录制\n\n```bash\n$ curl -X POST 10.0.0.1:7912/screenrecord\n```\n\n停止录制并获取录制结果\n\n```bash\n$ curl -X PUT 10.0.0.1:7912/screenrecord\n{\n    \"videos\": [\n        \"/sdcard/screenrecords/0.mp4\",\n        \"/sdcard/screenrecords/1.mp4\"\n    ]\n}\n```\n\n之后再下载到本地\n\n```bash\n$ curl -X GET 10.0.0.1:7912/raw/sdcard/screenrecords/0.mp4\n```\n\n## Minitouch操作方法\n感谢 [openstf/minitouch](https://github.com/openstf/minitouch)\n\nWebsocket连接 `$DEVICE_URL/minitouch`, 一行行的按照JSON的格式写入\n\n\u003e注: 坐标原点始终是手机正放时候的左上角，使用者需要自己处理旋转的变化\n\n请先详细阅读minitouch的[Usage](https://github.com/openstf/minitouch#usage)文档，再来看下面的部分\n\n- Touch Down\n\n    坐标(X: 50%, Y: 50%), index代表第几个手指, `pressure`是可选的。\n\n    ```json\n    {\"operation\": \"d\", \"index\": 0, \"xP\": 0.5, \"yP\": 0.5, \"pressure\": 50}\n    ```\n\n- Touch Commit\n\n    ```json\n    {\"operation\": \"c\"}\n    ```\n\n- Touch Move\n\n    ```json\n    {\"operation\": \"m\", \"index\": 0, \"xP\": 0.5, \"yP\": 0.5, \"pressure\": 50}\n    ```\n\n- Touch Up\n\n    ```json\n    {\"operation\": \"u\", \"index\": 0}\n    ```\n\n- 点击x:20%, y:20,滑动到x:40%, y:50%\n\n    ```json\n    {\"operation\": \"d\", \"index\": 0, \"xP\": 0.20, \"yP\": 0.20, \"pressure\": 50}\n    {\"operation\": \"c\"}\n    {\"operation\": \"m\", \"index\": 0, \"xP\": 0.40, \"yP\": 0.50, \"pressure\": 50}\n    {\"operation\": \"c\"}\n    {\"operation\": \"u\", \"index\": 0}\n    {\"operation\": \"c\"}\n    ```\n\n# TODO\n1. 目前安全性还是个问题，以后再想办法改善\n2. 补全接口文档\n3. 内置的网页adb shell的安全问题\n\n# Logs\nlog path `/sdcard/atx-agent.log`\n\n## TODO\n- [ ] 使用支持多线程下载的库 https://github.com/cavaliercoder/grab\n\n# LICENSE\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenatx%2Fatx-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenatx%2Fatx-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenatx%2Fatx-agent/lists"}