当前位置:首页 > 技术文章 > 正文内容

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

u3blog1年前 (2022-10-08)技术文章378

前排提示

本文中所描述工具只在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是不行的,遗憾

那么大家下次再见

扫描二维码推送至手机访问。

版权声明:本文由u3blog发布,如需转载请注明出处。

本文链接:https://u3blog.xyz/?id=697

分享给朋友:

“彻底摆脱数据线——远程ADB调试小工具开发过程记录 ” 的相关文章

开源数据库Postgresql安装/卸载总结

What Postgresql一个开源数据库,类似mysql,由于mysql被收购了,这个数据库正被越来越多的使用 怎么安装?安装非常简单,但是安装过后的初始化还是有点麻烦,具体可以看这篇文章为什么要卸载?安装好之后,如果你很倒霉的话,会遇到postgresql服务怎么都启动不了,输入psql指令显...

AndroidStudio插件开发——RemoveButterKnife从构思到实现

AndroidStudio插件开发——RemoveButterKnife从构思到实现

ReomveButterKnife插件这是一个用于移除代码中对ButterKnife使用的AS插件,接下来我们将从头开始讲讲AS插件开发和这个插件的开发过程地址是<a href="https://github.com/u3shadow/RemoveButterKnife"...

项目的改造——RemoveButterKnife插件代码的重构

项目的改造——RemoveButterKnife插件代码的重构

前言这篇文章记述了我的插件RemoveButterKnife的代码改进过程以及思路,关于插件,各位可以看RemoveButterKnife代码库,关于文章,可以看构思到实现RemoveButterKnife 原因近期想给原来的插件RemoveButterKnife加入一些新的功能,发现以前的代码没...

项目的升级-给RemoveButterKnife插件增加新功能

项目的升级-给RemoveButterKnife插件增加新功能

前言经过项目的初步编写和进一步改造,RemoveButterKnife插件终于也有模有样了,但是,功能上仅仅支持Activity/Fragment的BindView注解。 关于编写和优化的过程可以看下面两篇文章项目构造RemoveButterKnife 项目改进-重构RemoveButterKn...

Android测试体系-在MVVM架构中如何测试Model层与ViewModel层

背景此文章是对于google code lab中《Introduction to Test Double and Dependence injection》 与 《Testing Basics》的总结,本篇主要讲述如何在mvvm架构的android项目中对Model层以及ViewModel层进行测试...

使用Databinding为Recyclerview使用同一个ViewHolder加载不同Item

提示:在阅读本篇文章前,你最好对android databinding有一定了解,本文使用的代码均为kotlin,但是不用担心,都很简单 最近在写项目的时候使用了databinding技术,突发奇想,databinding是不是也能应用于recyclerview中,让加载多个不同的item更简单呢...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。