6

彻底摆脱数据线——远程ADB调试小工具开发过程记录

 3 years ago
source link: http://www.u3coding.com/2020/10/14/remoteadblog/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

本文中所描述工具只在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"
                    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.找到方法了之后,执行哪些命令才能达到我们的目的?

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

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

那么大家下次再见


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK