惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
阮一峰的网络日志
阮一峰的网络日志
云风的 BLOG
云风的 BLOG
D
Docker
Vercel News
Vercel News
IT之家
IT之家
Recent Announcements
Recent Announcements
Last Week in AI
Last Week in AI
V
Visual Studio Blog
Engineering at Meta
Engineering at Meta
腾讯CDC
Google DeepMind News
Google DeepMind News
I
InfoQ
博客园 - 三生石上(FineUI控件)
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
博客园 - Franky
The Cloudflare Blog
A
About on SuperTechFans
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
T
Tenable Blog
P
Proofpoint News Feed
Recorded Future
Recorded Future
Security Latest
Security Latest
H
Hackread – Cybersecurity News, Data Breaches, AI and More
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 聂微东
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google Online Security Blog
Google Online Security Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Simon Willison's Weblog
Simon Willison's Weblog
The Last Watchdog
The Last Watchdog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
U
Unit 42
The Hacker News
The Hacker News
Martin Fowler
Martin Fowler
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
F
Full Disclosure
M
MIT News - Artificial intelligence
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
V
V2EX
Project Zero
Project Zero

u3blog

从手动配置到自然语言生成规则:一个 Android AI 工具的重构实录 - u3blog 学习版游戏自制云存档同步的方法探索以及总结 - u3blog 鸿蒙next中web组件和navigation的一个bug以及处理方案 - u3blog ChatGPT是怎么帮我写ios代码的 - u3blog Android项目cicd流程总结(使用jenkins) - u3blog Android使用Logger开发App本地日志记录功能 - u3blog 一张启动图引发的思考--探索.9图原理和应用场景 - u3blog 跟我一起玩Paging3 - u3blog Android中使用ASPECTJ进行用户操作路径跟踪与日志搜集 - u3blog 自己实现一个Android网络图片加载器 - u3blog
彻底摆脱数据线——远程ADB调试小工具开发过程记录 - u3blog
2022-10-08 · via u3blog

前排提示

本文中所描述工具只在ROOT过的设备上有效,如果不感兴趣的朋友可以点赞后退出了,也可以去github给我点个星星,源码地址在这里

写在开始前

每次重启测试机都要连接usb才能开始远程adb调试,真麻烦,能不能弄一个软件点一下就能开始远程调试呢?

如果对什么是adb远程调试不熟悉的朋友,可以搜索下adb tcpip 5555这条命令

为了解决每次重启都要连接一次电脑的问题,经过了大量的网络搜索,终于解决了这个问题。

本文记录了从提出问题到解决问题的全过程。

提问环节

  • 1.为什么要做这个工具?

    adb提供的远程调试工具不香吗,为什么还要没事找事折腾半天来做这个工具

  • 2.怎么实现不连接Usb启动adb的远程连接模式?

    通过往常的经验来看,各种实现远程调试的插件都需要连接一次usb,看起来不用usb好像不太现实,但是经过调研,确实是可以的

  • 3.找到方法了之后,执行哪些命令才能达到我们的目的?

    看似简单的几行命令,到了Android手机上怎么就老跑不通呢

    ** 带着上面这几个问题,我们开始今天的探索吧**

    为什么

    博主有一台很棒的测试机,它叫小6,小6有很多优点,速度快,体积小,操作简单。
    既然小6如此优秀,为什么还会有这篇博客呢,其实小6有一个致命问题,电池不耐用,毕竟已经退役成测试机了嘛。

    每次博主要远程调试的时候,小6都需要重新连一次电脑,对于一个电脑只有两个usb口的博主来说,这个过程非常的痛苦,特别是小6的电池又不耐用,每天晚上都会自动关机睡一觉。

    所以博主我想,能不能把连电脑这一个步骤转移到手机上执行呢,看着命令也挺简单的,只有一行

    感觉我上我也行嘛,说做就做,马上来试试

    adb tcpip 5555

    adb tcpip 5555 做了些什么

    这是一条神奇的命令,手机开启调试模式,连上电脑之后,运行它,我们就可以用ip连接手机,不用数据线调试程序了

经过一番查找,我们发现,这条命令发送了几条命令给手机

  • 1.设置service.adb.tcp.port为5555
  • 2.重启手机上的adb

搜到这里,博主激动了起来,看起来好像很简单啊,我在手机上也这么操作不就行了,马上去找找怎么在手机上执行命令行

在手机上运行它们!

Android上有很多命令行工具,博主随便找了一个,叫做Termux,运行了上面两条命令

报错了,not found 是什么鬼?经过一番搜索,原来是没有root权限

** 那我们只有去root手机了**

我们来看看root之后再运行怎么样

在获取root权限之后,报错消失了,太好了!

我们继续运行接下来两个命令

运行成功了,我们现在就可以在电脑上用下面的命令来连接手机了

adb connect 手机的ip:5555 

在自己的代码里运行命令

目前为止,一切都很顺利,我们不想用第三方的app,自己写一个程序,点一下,玩一年,不用数据线一整年

怎么在代码里运行shell命令呢?

经过又一番搜索,博主找到了几种方法,最终选定了下面这种,su可以替换成其他命令

 Runtime.getRuntime().exec("su")

让我们行动起来,运行三行命令吧

好像没有作用,尴尬

对比三方应用和自己的命令

通过对比,我们发现第三方的客户端的用户好像不太一样啊,经过搜索,我们发现是它调用了一下/system/bin/sh

我们也得给自己的代码加上才行

我们看看改完之后的命令

运行检测一下,成功啦!

优化一下使用体验

现在我们实现了基本的功能,但是不太友好,对于没有root的用户我们要提醒他,你不能用这个玩意,对于已经root的用户,操作成功了我们要提示他现在的ip是什么,用什么命令连接

这个很简单,弄完就像下面这样,其中的ip我们要去获取手机现在的ip地址

放出代码

前面比比了那么多,代码拿出来看看啊,别急,下面就是完整的代码

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
            val wm = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
            val ip: String = Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
            AlertDialog.Builder(this).setMessage("该程序仅工作在拥有root权限设备上,如果没有root,请连接usb并使用下列命令进行远程调试\nadb tcpip 5555\nadb connect $ip:5555").setPositiveButton(
                "确认"
            ) { _, _ ->
                val commands = arrayListOf(
                    "/system/bin/sh",
                    "setprop service.adb.tcp.port 5555",
                    "stop adbd",
                    "start adbd"
                )
                try {
                    RunAsRoot(commands)
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }.setCancelable(false).show()

    }

    private fun RunAsRoot(cmds: ArrayList<String>) {
        val p = Runtime.getRuntime().exec("su")
        val os = DataOutputStream(p.outputStream)
        for (tmpCmd in cmds) {
            os.writeBytes(
                """
                $tmpCmd

                """.trimIndent()
            )
        }
        os.writeBytes("exit\n")
        os.flush()
        val wm = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
        val ip: String = Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
        AlertDialog.Builder(this).setMessage("设置完成,请在同一局域网下使用以下命令连接设备\nadb connect $ip:5555").setPositiveButton(
            "确认"
        ) { _, _ -> finish() }.setCancelable(false).show()
    }

}

相信看完上面的介绍,代码应该不难看懂,如果不想自己写,可以去这里找到源码,直接复制粘贴一把梭

问题回顾

让我们来看看最开始的几个问题,总结一下

  • 1.为什么要做这个工具?

    我们的测试机可以重启后不连接usb启动远程调试模式啦!

  • 2.怎么实现不连接Usb启动adb的远程连接模式?

    在代码里运行命令就可以了,用Runtime.getRuntime().exec(你的命令)

  • 3.找到方法了之后,执行哪些命令才能达到我们的目的?

    下面这些

         su
         /system/bin/sh
         setprop service.adb.tcp.port 5555
         stop adbd
         start adbd

写在最后

终极问题,能不能不用root实现这套操作?不能,即使设置端口成功了,重启手机上adb的操作也需要su权限,所以不root是不行的,遗憾

那么大家下次再见