在 android 上使用 adb client

news2024/12/25 9:41:01

adb tool 分为 adb 和 adbd。 adb 用作 host 使用,包含了client和server,adbd 则作为 device 端,在 android 源码目录下,共用一套源码。但 android 源码下的 adb,不支持把 adb 编译为 android 平台的 adb client。因此需要自己进行交叉编译。

参考链接:

https://blog.csdn.net/disappears_nick/article/details/117031743

https://gitee.com/jackackcheng/android-tools-4.2.2

1. 下载源码

参考上面的链接,直接使用经过版本验证源码。

git clone https://gitee.com/jackackcheng/android-tools-4.2.2

由于平台架构是aarch64的android11,因此一般的工具链可能用不了。下载 android-ndk-r25c ,里面包含有 aarch64-linux-android30-clang 工具链,位于 android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/

添加临时环境变量:

export PATH=$PATH:$path/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/

可以编译个简单的helloworld,放到android上看看能不能运行,测试工具链是否可用。

2. 编译zlib

解压 zlib-1.2.11.tar.gz :

tar -xzvf zlib-1.2.11.tar.gz

配置编译环境:

./configure --prefix=$(pwd)/../libz --static

由于 clang 编译器和 gcc 编译器的命令规则不一样,因此直接上面配置环境时指定工具链会有问题。

因此,在配置好环境后,通过直接修改Makefile来解决这个问题。执行上述命令后,目录下会生成 Makefile。打开Makefile,修改其中和工具链相关的配置:

CC=aarch64-linux-android30-clang
LDSHARED=aarch64-linux-android30-clang
CPP=aarch64-linux-android30-clang++
AR=llvm-ar
RANLIB=llvm-ranlib

每次执行 ./configure ,都会导致Makefile的重新生成。可以在修改后,对Makefile做个备份。

编译:

make -j20 
make install -j20

在这里插入图片描述

安装后,会在上层目录 libz 下生成 includelib ,包含了供我们使用的头文件和静态库。

3. 编译openssl

和编译zlib一样,先配置好环境,然后修改 Makefile,指定 aarch64-linux-android30-clang 作为工具链。

解压 openssl-1.0.0e.tar.gz:

tar -xzvf openssl-1.0.0e.tar.gz

配置编译环境:

./Configure static os/compiler:aarch64-linux-android30-clang --prefix=$(pwd)/../libopenssl

修改Makefile:

CC= aarch64-linux-android30-clang
AR= llvm-ar $(ARFLAGS) r
RANLIB= llvm-ranlib
NM= llvm-nm

编译:

make -j20
make install 

在这里插入图片描述

在这里插入图片描述

安装后,会在上层目录 libopenssl 下生成 includelib ,包含了供我们使用的头文件和静态库。

4. 编译adb

进入到 android-tools-4.2.2/core/adb 目录下,里面已经由写好的 Makefile了,只需要修改工具链即可。这里我们使用静态链接,方便直接拷贝adb进行使用,避免环境问题。

修改Makefile,指定编译生成的 zlib 和 openssl 的头文件路径和静态库文件路径:

CC:=aarch64-linux-android30-clang

CPPFLAGS+= -I/media/data1/library/tmp/2_adb/android-tools-4.2.2/libopenssl/include
CPPFLAGS+= -I/media/data1/library/tmp/2_adb/android-tools-4.2.2/libz/include

LIBS+= -lc -pthread /media/data1/library/tmp/2_adb/android-tools-4.2.2/libz/lib/libz.a /media/data1/library/tmp/2_adb/android-tools-4.2.2/libopenssl/lib/libcrypto.a

编译:

make -j20

在这里插入图片描述

不出意外,目录下会生成 adb ,这个上传到 android 上,就可以用了。

5. 使用问题

通过上述流程编译的 adb,在 android 上运行是没有问题了。但是确无法识别设备,需要解决一些bug才行。

下面是遇到的问题和解决办法。

5.1 无法启动 server

/ # adb devices
* daemon not running. starting it now on port 5040 *
* daemon started successfully *
** daemon still not running
error: cannot connect to daemon

这个问题,在交叉编译到 aarch64 的 Linux上时,不会出现。

如果 $HOME 目录下面有 .android/adb_usb.ini 文件,会从这个文件中读取 usb vendor id。

    if (get_adb_usb_ini(temp, sizeof(temp)) == 0) {
        FILE * f = fopen(temp, "rt");

        if (f != NULL) {
            /* The vendor id file is pretty basic. 1 vendor id per line.
               Lines starting with # are comments */
            while (fgets(temp, sizeof(temp), f) != NULL) {
                if (temp[0] == '#')
                    continue;

                long value = strtol(temp, NULL, 0);
                printf("vendor id: 0x%lx\n", value);
                if (errno == EINVAL || errno == ERANGE || value > INT_MAX || value < 0) {
                    printf("errno: %s\n", strerror(errno));
                    fprintf(stderr, "Invalid content in %s. Quitting.\n", ANDROID_ADB_INI);
                    exit(2);
                }

                vendorIds[vendorIdCount++] = (int)value;

                /* make sure we don't go beyond the array */
                if (vendorIdCount == VENDOR_COUNT_MAX) {
                    break;
                }
            }
        }
    }

这里 errno 在 main 函数进入时,就已经是 Invalid argument 状态了,因此在这里会导致程序退出。暂不清楚是什么原因导致的 errno 是错误状态。因此,在 main 最开始的地方, 把 errno 置 0即可。

int main(int argc, char **argv)
{
    errno = 0;
#if ADB_HOST
}

5.2 ADB server didn’t ACK

/ # adb devices
service: host:devices
* daemon not running. starting it now on port 5040 *
ADB server didn't ACK
* failed to start daemon *
error: cannot connect to daemon

和上述原因一样,是由于errno问题意外退出导致的。adb 会默认先fork一个进程,运行 adb server,然后通过管道读取输出信息,读取到 “OK\n” 后,才会往下执行。在读取 OK 的位置添加读取信息并打印,发现读取到的是如下内容:

temp: Invalid content in adb_usb.ini.
temp: Quitting.

fork 的 子进程启动 server 时,遇到 5.1 无法启动 server 的问题,退出并打印上述错误信息,然后被父进程读到。

5.3 无法识别到device

默认adb只识别支持的 usb vendor id 列表的设备。如果设备不在支持列表,那么是无法识别的。需要添加 device 的 usb vendor id 到 usb_vendor.c 中:

/** built-in vendor list */
int builtInVendorIds[] = {
    VENDOR_ID_GOOGLE,
    VENDOR_ID_INTEL,
    VENDOR_ID_HTC,
    VENDOR_ID_SAMSUNG,
    VENDOR_ID_MOTOROLA,
    VENDOR_ID_LGE,
    VENDOR_ID_HUAWEI,
    VENDOR_ID_ACER,
    VENDOR_ID_SONY_ERICSSON,
    VENDOR_ID_FOXCONN,
    VENDOR_ID_DELL,
    VENDOR_ID_NVIDIA,
    0x2c7c,
    ....

或者 创建 $HOME/.android/adb_usb.ini 文件,将需要识别设备的 usb vendor id写入到这个文件中:

echo 0x2c7c > $HOME/.android/adb_usb.ini
/ # adb devices
List of devices attached
f9618ed6        device
emulator-5554   device

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1034888.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

气传导耳机哪个品牌比较好?推荐几款很不错的气传导耳机

​气传导耳机是一种新型耳机类型&#xff0c;采用不入耳设计&#xff0c;上耳佩戴更加舒适稳固&#xff0c;还可以为你带来更加自然和舒适的听觉体验&#xff0c;同时满足你对周围环境的需求。面对市面上这么多气传导耳机&#xff0c;不知道该如何挑选时&#xff0c;也不用过于…

web二级操作题

js和css的引入 在 HTML 中&#xff0c;你可以使用 <script> 和 <link> 标签来引入外部的 JavaScript 文件和 CSS 文件。 引入外部的 JavaScript 文件&#xff1a; <script src"path/to/script.js"></script>src 属性指定了 JavaScript 文…

【已解决】ubuntu 16.04安装最新版本google chrome出错, 旧版本chrome浏览器安装流程

ubuntu 16.04 按照常规的Chrome 安装流程总是出错如下&#xff1a; Selecting previously unselected package google-chrome-stable. (Reading database ... 231747 files and directories currently installed.) Preparing to unpack google-chrome-stable_current_amd64.de…

阈值化分割,对灰度级图像进行二值化处理(数字图像处理大题复习 P8)

文章目录 画出表格求出灰度直方图 & 山谷画出结果图 画出表格 有几个0就写几&#xff0c;有几个1就写几&#xff0c;如图 求出灰度直方图 & 山谷 跟前面求灰度直方图的方法一样&#xff0c;找出谷底&#xff0c;发现结果为 4 画出结果图 最终的结果就是&#xf…

【Seata】seata的部署和集成

一、部署Seata的tc-server 1.下载 首先我们要下载seata-server包&#xff0c;地址在http://seata.io/zh-cn/blog/download.html 当然&#xff0c;课前资料也准备好了&#xff1a; 2.解压 在非中文目录解压缩这个zip包&#xff0c;其目录结构如下&#xff1a; 3.修改配置 修…

解决ubuntu系统python2.7安装uwsgi报错

背景 因为项目老旧&#xff0c;仍需使用python2.7&#xff0c;仍需要使用pip2 安装依赖。在安装uwsgi的时候&#xff0c;报错。 错误一 Building wheel for uwsgi (setup.py) ... error ERROR: Command errored out with exit status 1: command: /usr/bin/python2 -u -…

IBMMQ 安装教程(IBM WebSphere MQ 安装教程)- 及 IBMMQ 服务器搭建教程

文章目录 前言一、下载二、安装1. 解压&#xff0c;运行 Setup.exe 文件。2. 启动 IBM WebSphere MQ 安装程序。3. 接受用户协议。4. 选择定制安装。5. 更改安装目录。6. 下一步。7. 下一步。8. 下一步。9. 点击安装。10. 等待安装&#xff0c;完成。11. 准备安装 WebSphere MQ…

Day_15 > 内存相关的函数

目录 1.memcpy 1.1memcpy函数的使用 1.2memcpy函数的模拟实现 2.memmove 2.1memcpy存在的局限性 2.2memmove函数的使用 2.3memmove函数的模拟实现 3.memset 3.1memset函数的使用 4.memcmp 4.1memcpy函数的使用 之前我们可能了解过字符串函数&#xff0c;今天我们了解…

如何使用固态硬盘+硬盘盒子+U盘创造移动双系统

本文背景 这学期上了一节鸟水课《大数据实践》&#xff0c;老师要求扩展硬盘盒&#xff0c;以部署大数据工具进行 机器挖掘等大数据领域工作 参考视频链接&#xff1a;无需启动盘&#xff0c;用虚拟机将ubuntu安装到移动硬盘上_哔哩哔哩_bilibili 项目使用设备 1.绿联&#…

C/C++运算符超详细讲解(系统性学习day5)

目录 前言 一、运算符的概念与分类 二、算术运算符 三、关系运算符 四、逻辑运算符 五、赋值运算符 六、运算符的优先级 总结 前言 本篇文章是对运算符的具体讲解。 一、运算符的概念与分类 概念&#xff1a; 运算符就是一种告诉编译器执行特定的数学或逻辑操作的符…

Ubuntu出现无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend),是否有其他进程正占用它?

1、在Ubuntu系统安装sublime是出现以下这个问题&#xff1a; 解决方法&#xff1a; 使用以下命令强制解锁&#xff1a;&#xff08;删除“/var/lib/dpkg”目录下的 “lock-frontend” 和“lock”两个文件&#xff09; sudo rm /var/lib/dpkg/lock-frontend sudo rm /var/lib/…

代码随想录算法训练营第56天|583. 两个字符串的删除操作,72. 编辑距离 (昨天的疑虑今天豁然开朗了)

链接: 583. 两个字符串的删除操作 链接: 72. 编辑距离 583. 两个字符串的删除操作 class Solution {public int minDistance(String word1, String word2) {int len1 word1.length(), len2 word2.length();int[][] dp new int[len1 1][len2 1];for (int i 0; i < le…

Android开发笔记 :理解Fragment

Android开发笔记&#xff1a;理解Fragment 导言 本篇文章产生的原因很简单&#xff0c;就是我在了解Android Jetpack中的Lifecycle框架时发现Lifecycle具体时间和状态的更新都是由一个名为ReportFragment的Fragment来跟踪的&#xff0c;为了更好的了解Fragment是如何追踪Activ…

【软件测试】测试中的风险有哪些?

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程&#xff0c;刷完面试就稳了&#xff0c;你也可以当高薪软件测试工程师&#xff08;自动化测试&#xff09; ​那么到底都有哪些风险要注意呢?如何解决呢?另外这些风险如何在计划中写明呢&#xff0c;不会写“张三…

汇编语言课程设计1 代码 优化版

assume cs:codesgstacksg segmentdw 16 dup(0) stacksg endsdatasg segmentdb 1975,1976,1977,1978,1979,1980,1981,1982,1983db 1984,1985,1986,1987,1988,1989,1990,1991,1992db 1993,1994,1995;以上是表示21年的21个字符串dd 16,22,382,1356,2390,8000,16000,24286,50065,97…

基于Java的酒店管理系统设计与实现(源码+lw+部署文档+讲解等)

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…

文件-计算平均分

任务描述 本关任务&#xff1a;假设有若干学生&#xff0c;每个学生有3门功课&#xff0c;从键盘上输入学生有关信息&#xff08;学号、姓名、成绩&#xff09;&#xff0c;并计算其平均成绩&#xff0c;将原有数据和平均分保存在磁盘文件record中。具体要求如下: 学生有关信…

【计算机毕业设计】基于SpringBoot+Vue大学生心理健康管理系统的开发与实现

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题…

计算机图形学中的几何光学

文章目录 前言一、图形学中的光学二、光照模型1、经验型&#xff08;简单&#xff09;2、物理型&#xff08;复杂&#xff09; 前言 在学习Shader光照之前了解一下计算机图形学 一、图形学中的光学 镜面反射的效果例子&#xff1a;物体表面高光 慢反射的效果的例子&#xff1a…

Python中获取主机名和IP地址的方法

在Python中&#xff0c;可以通过socket模块中gethostname()、getfqdn()和gethostbyname()方法获取本地和远程主机名和IP地址。 1 获取本地和远程主机名 1.1 获取本地主机名 可以通过gethostname()方法获取本地主机名&#xff0c;也就是本机的主机名&#xff0c;代码如下所示…