ADB(1)(字数限制拆分)

# ADB ADB,即 [Android Debug Bridge](https://developer.android.com/studio/command-line/adb.html),它是 Android 开发/测试人员不可替代的强大工具,也是 Android 设备玩家的好玩具。 持续更新中 **注:** 有部分命令的支持情况可能与 Android 系统版本及定制 ROM 的实现有关。 # Table of Contents ## 基本用法 ### 命令语法 adb 命令的基本语法如下: ```sh adb [-d|-e|-s <serialNumber>] <command> ``` 如果只有一个设备/模拟器连接时,可以省略掉 `[-d|-e|-s <serialNumber>]` 这一部分,直接使用 `adb <command>`。 ### 为命令指定目标设备 如果有多个设备/模拟器连接,则需要为命令指定目标设备。 | 参数 | 含义 | |---------------------|----------------------------------------------------| | -d | 指定当前唯一通过 USB 连接的 Android 设备为命令目标 | | -e | 指定当前唯一运行的模拟器为命令目标 | | `-s <serialNumber>` | 指定相应 serialNumber 号的设备/模拟器为命令目标 | 在多个设备/模拟器连接的情况下较常用的是 `-s <serialNumber>` 参数,serialNumber 可以通过 `adb devices` 命令获取。如: ```sh $ adb devices List of devices attached cf264b8f device emulator-5554 device 10.129.164.6:5555 device ``` 输出里的 `cf264b8f`、`emulator-5554` 和 `10.129.164.6:5555` 即为 serialNumber。 比如这时想指定 `cf264b8f` 这个设备来运行 adb 命令获取屏幕分辨率: ```sh adb -s cf264b8f shell wm size ``` 又如想给 `10.129.164.6:5555` 这个设备安装应用(*这种形式的 serialNumber 格式为 `<IP>:<Port>`,一般为无线连接的设备或 Genymotion 等第三方 Android 模拟器*): ```sh adb -s 10.129.164.6:5555 install test.apk ``` **遇到多设备/模拟器的情况均使用这几个参数为命令指定目标设备,下文中为简化描述,不再重复。** ### 启动/停止 启动 adb server 命令: ```sh adb start-server ``` (一般无需手动执行此命令,在运行 adb 命令时若发现 adb server 没有启动会自动调起。) 停止 adb server 命令: ```sh adb kill-server ``` ### 查看 adb 版本 命令: ```sh adb version ``` 示例输出: ```sh Android Debug Bridge version 1.0.36 Revision 8f855a3d9b35-android ``` ### 以 root 权限运行 adbd adb 的运行原理是 PC 端的 adb server 与手机端的守护进程 adbd 建立连接,然后 PC 端的 adb client 通过 adb server 转发命令,adbd 接收命令后解析运行。 所以如果 adbd 以普通权限执行,有些需要 root 权限才能执行的命令无法直接用 `adb xxx` 执行。这时可以 `adb shell` 然后 `su` 后执行命令,也可以让 adbd 以 root 权限执行,这个就能随意执行高权限命令了。 命令: ```sh adb root ``` 正常输出: ```sh restarting adbd as root ``` 现在再运行 `adb shell`,看看命令行提示符是不是变成 `#` 了? 有些手机 root 后也无法通过 `adb root` 命令让 adbd 以 root 权限执行,比如三星的部分机型,会提示 `adbd cannot run as root in production builds`,此时可以先安装 adbd Insecure,然后 `adb root` 试试。 相应地,如果要恢复 adbd 为非 root 权限的话,可以使用 `adb unroot` 命令。 ### 指定 adb server 的网络端口 命令: ```sh adb -P <port> start-server ``` 默认端口为 5037。 ## 设备连接管理 ### 查询已连接设备/模拟器 命令: ```sh adb devices ``` 输出示例: ```sh List of devices attached cf264b8f device emulator-5554 device 10.129.164.6:5555 device ``` 输出格式为 `[serialNumber] [state]`,serialNumber 即我们常说的 SN,state 有如下几种: * `offline` —— 表示设备未连接成功或无响应。 * `device` —— 设备已连接。注意这个状态并不能标识 Android 系统已经完全启动和可操作,在设备启动过程中设备实例就可连接到 adb,但启动完毕后系统才处于可操作状态。 * `no device` —— 没有设备/模拟器连接。 以上输出显示当前已经连接了三台设备/模拟器,`cf264b8f`、`emulator-5554` 和 `10.129.164.6:5555` 分别是它们的 SN。从 `emulator-5554` 这个名字可以看出它是一个 Android 模拟器,而 `10.129.164.6:5555` 这种形为 `<IP>:<Port>` 的 serialNumber 一般是无线连接的设备或 Genymotion 等第三方 Android 模拟器。 常见异常输出: 1. 没有设备/模拟器连接成功。 ```sh List of devices attached ``` 2. 设备/模拟器未连接到 adb 或无响应。 ```sh List of devices attached cf264b8f offline ``` ### USB 连接 通过 USB 连接来正常使用 adb 需要保证几点: 1. 硬件状态正常。 包括 Android 设备处于正常开机状态,USB 连接线和各种接口完好。 2. Android 设备的开发者选项和 USB 调试模式已开启。 可以到「设置」-「开发者选项」-「Android 调试」查看。 如果在设置里找不到开发者选项,那需要通过一个彩蛋来让它显示出来:在「设置」-「关于手机」连续点击「版本号」7 次。 3. 设备驱动状态正常。 这一点貌似在 Linux 和 Mac OS X 下不用操心,在 Windows 下有可能遇到需要安装驱动的情况,确认这一点可以右键「计算机」-「属性」,到「设备管理器」里查看相关设备上是否有黄色感叹号或问号,如果没有就说明驱动状态已经好了。否则可以下载一个手机助手类程序来安装驱动先。 4. 通过 USB 线连接好电脑和设备后确认状态。 ```sh adb devices ``` 如果能看到 ```sh xxxxxx device ``` 说明连接成功。 ### 无线连接(需要借助 USB 线) 除了可以通过 USB 连接设备与电脑来使用 adb,也可以通过无线连接——虽然连接过程中也有需要使用 USB 的步骤,但是连接成功之后你的设备就可以在一定范围内摆脱 USB 连接线的限制啦! 操作步骤: 1. 将 Android 设备与要运行 adb 的电脑连接到同一个局域网,比如连到同一个 WiFi。 2. 将设备与电脑通过 USB 线连接。 应确保连接成功(可运行 `adb devices` 看是否能列出该设备)。 3. 让设备在 5555 端口监听 TCP/IP 连接: ```sh adb tcpip 5555 ``` 4. 断开 USB 连接。 5. 找到设备的 IP 地址。 一般能在「设置」-「关于手机」-「状态信息」-「IP地址」找到,也可以使用下文里 [查看设备信息 - IP 地址][1] 一节里的方法用 adb 命令来查看。 6. 通过 IP 地址连接设备。 ```sh adb connect <device-ip-address> ``` 这里的 `<device-ip-address>` 就是上一步中找到的设备 IP 地址。 7. 确认连接状态。 ```sh adb devices ``` 如果能看到 ```sh <device-ip-address>:5555 device ``` 说明连接成功。 如果连接不了,请确认 Android 设备与电脑是连接到了同一个 WiFi,然后再次执行 `adb connect <device-ip-address>` 那一步; 如果还是不行的话,通过 `adb kill-server` 重新启动 adb 然后从头再来一次试试。 **断开无线连接** 命令: ```sh adb disconnect <device-ip-address> ``` ### 无线连接(无需借助 USB 线) **注:需要 root 权限。** 上一节「无线连接(需要借助 USB 线)」是官方文档里介绍的方法,需要借助于 USB 数据线来实现无线连接。 既然我们想要实现无线连接,那能不能所有步骤下来都是无线的呢?答案是能的。 1. 在 Android 设备上安装一个终端模拟器。 已经安装过的设备可以跳过此步。我使用的终端模拟器下载地址是:[Terminal Emulator for Android Downloads](https://jackpal.github.io/Android-Terminal-Emulator/) 2. 将 Android 设备与要运行 adb 的电脑连接到同一个局域网,比如连到同一个 WiFi。 3. 打开 Android 设备上的终端模拟器,在里面依次运行命令: ```sh su setprop service.adb.tcp.port 5555 ``` 4. 找到 Android 设备的 IP 地址。 一般能在「设置」-「关于手机」-「状态信息」-「IP地址」找到,也可以使用下文里 [查看设备信息 - IP 地址][1] 一节里的方法用 adb 命令来查看。 5. 在电脑上通过 adb 和 IP 地址连接 Android 设备。 ```sh adb connect <device-ip-address> ``` 这里的 `<device-ip-address>` 就是上一步中找到的设备 IP 地址。 如果能看到 `connected to <device-ip-address>:5555` 这样的输出则表示连接成功。 *节注一:* 有的设备,比如小米 5S + MIUI 8.0 + Android 6.0.1 MXB48T,可能在第 5 步之前需要重启 adbd 服务,在设备的终端模拟器上运行: ```sh restart adbd ``` 如果 restart 无效,尝试以下命令: ```sh stop adbd start adbd ``` ## 应用管理 ### 查看应用列表 查看应用列表的基本命令格式是 ```sh adb shell pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER] ``` 即在 `adb shell pm list packages` 的基础上可以加一些参数进行过滤查看不同的列表,支持的过滤参数如下: | 参数 | 显示列表 | |------------|----------------------------| | 无 | 所有应用 | | -f | 显示应用关联的 apk 文件 | | -d | 只显示 disabled 的应用 | | -e | 只显示 enabled 的应用 | | -s | 只显示系统应用 | | -3 | 只显示第三方应用 | | -i | 显示应用的 installer | | -u | 包含已卸载应用 | | `<FILTER>` | 包名包含 `<FILTER>` 字符串 | #### 所有应用 命令: ```sh adb shell pm list packages ``` 输出示例: ```sh package:com.android.smoketest package:com.example.android.livecubes package:com.android.providers.telephony package:com.google.android.googlequicksearchbox package:com.android.providers.calendar package:com.android.providers.media package:com.android.protips package:com.android.documentsui package:com.android.gallery package:com.android.externalstorage ... // other packages here ... ``` #### 系统应用 命令: ```sh adb shell pm list packages -s ``` #### 第三方应用 命令: ```sh adb shell pm list packages -3 ``` #### 包名包含某字符串的应用 比如要查看包名包含字符串 `mazhuang` 的应用列表,命令: ```sh adb shell pm list packages mazhuang ``` 当然也可以使用 grep 来过滤: ```sh adb shell pm list packages | grep mazhuang ``` ### 安装 APK 命令格式: ```sh adb install [-lrtsdg] <path_to_apk> ``` 参数: `adb install` 后面可以跟一些可选参数来控制安装 APK 的行为,可用参数及含义如下: | 参数 | 含义 | |------|-----------------------------------------------------------------------------------| | -l | 将应用安装到保护目录 /mnt/asec | | -r | 允许覆盖安装 | | -t | 允许安装 AndroidManifest.xml 里 application 指定 `android:testOnly="true"` 的应用 | | -s | 将应用安装到 sdcard | | -d | 允许降级覆盖安装 | | -g | 授予所有运行时权限 | 运行命令后如果见到类似如下输出(状态为 `Success`)代表安装成功: ```sh [100%] /data/local/tmp/1.apk pkg: /data/local/tmp/1.apk Success ``` 上面是当前最新版 v1.0.36 的 adb 的输出,会显示 push apk 文件到手机的进度百分比。 使用旧版本 adb 的输出则是这样的: ```sh 12040 KB/s (22205609 bytes in 1.801s) pkg: /data/local/tmp/SogouInput_android_v8.3_sweb.apk Success ``` 而如果状态为 `Failure` 则表示安装失败,比如: ```sh [100%] /data/local/tmp/map-20160831.apk pkg: /data/local/tmp/map-20160831.apk Failure [INSTALL_FAILED_ALREADY_EXISTS] ``` 常见安装失败输出代码、含义及可能的解决办法如下: | 输出 | 含义 | 解决办法 | |---------------------------------------------------------------------|--------------------------------------------------------------------------|------------------------------------------------------------------------------------| | INSTALL\_FAILED\_ALREADY\_EXISTS | 应用已经存在,或卸载了但没卸载干净 | `adb install` 时使用 `-r` 参数,或者先 `adb uninstall <packagename>` 再安装 | | INSTALL\_FAILED\_INVALID\_APK | 无效的 APK 文件 | | | INSTALL\_FAILED\_INVALID\_URI | 无效的 APK 文件名 | 确保 APK 文件名里无中文 | | INSTALL\_FAILED\_INSUFFICIENT\_STORAGE | 空间不足 | 清理空间 | | INSTALL\_FAILED\_DUPLICATE\_PACKAGE | 已经存在同名程序 | | | INSTALL\_FAILED\_NO\_SHARED\_USER | 请求的共享用户不存在 | | | INSTALL\_FAILED\_UPDATE\_INCOMPATIBLE | 以前安装过同名应用,但卸载时数据没有移除;或者已安装该应用,但签名不一致 | 先 `adb uninstall <packagename>` 再安装 | | INSTALL\_FAILED\_SHARED\_USER\_INCOMPATIBLE | 请求的共享用户存在但签名不一致 | | | INSTALL\_FAILED\_MISSING\_SHARED\_LIBRARY | 安装包使用了设备上不可用的共享库 | | | INSTALL\_FAILED\_REPLACE\_COULDNT\_DELETE | 替换时无法删除 | | | INSTALL\_FAILED\_DEXOPT | dex 优化验证失败或空间不足 | | | INSTALL\_FAILED\_OLDER\_SDK | 设备系统版本低于应用要求 | | | INSTALL\_FAILED\_CONFLICTING\_PROVIDER | 设备里已经存在与应用里同名的 content provider | | | INSTALL\_FAILED\_NEWER\_SDK | 设备系统版本高于应用要求 | | | INSTALL\_FAILED\_TEST\_ONLY | 应用是 test-only 的,但安装时没有指定 `-t` 参数 | | | INSTALL\_FAILED\_CPU\_ABI\_INCOMPATIBLE | 包含不兼容设备 CPU 应用程序二进制接口的 native code | | | INSTALL\_FAILED\_MISSING\_FEATURE | 应用使用了设备不可用的功能 | | | INSTALL\_FAILED\_CONTAINER\_ERROR | 1. sdcard 访问失败;<br />2. 应用签名与 ROM 签名一致,被当作内置应用。 | 1. 确认 sdcard 可用,或者安装到内置存储;<br />2. 打包时不与 ROM 使用相同签名。 | | INSTALL\_FAILED\_INVALID\_INSTALL\_LOCATION | 1. 不能安装到指定位置;<br />2. 应用签名与 ROM 签名一致,被当作内置应用。 | 1. 切换安装位置,添加或删除 `-s` 参数;<br />2. 打包时不与 ROM 使用相同签名。 | | INSTALL\_FAILED\_MEDIA\_UNAVAILABLE | 安装位置不可用 | 一般为 sdcard,确认 sdcard 可用或安装到内置存储 | | INSTALL\_FAILED\_VERIFICATION\_TIMEOUT | 验证安装包超时 | | | INSTALL\_FAILED\_VERIFICATION\_FAILURE | 验证安装包失败 | | | INSTALL\_FAILED\_PACKAGE\_CHANGED | 应用与调用程序期望的不一致 | | | INSTALL\_FAILED\_UID\_CHANGED | 以前安装过该应用,与本次分配的 UID 不一致 | 清除以前安装过的残留文件 | | INSTALL\_FAILED\_VERSION\_DOWNGRADE | 已经安装了该应用更高版本 | 使用 `-d` 参数 | | INSTALL\_FAILED\_PERMISSION\_MODEL\_DOWNGRADE | 已安装 target SDK 支持运行时权限的同名应用,要安装的版本不支持运行时权限 | | | INSTALL\_PARSE\_FAILED\_NOT\_APK | 指定路径不是文件,或不是以 `.apk` 结尾 | | | INSTALL\_PARSE\_FAILED\_BAD\_MANIFEST | 无法解析的 AndroidManifest.xml 文件 | | | INSTALL\_PARSE\_FAILED\_UNEXPECTED\_EXCEPTION | 解析器遇到异常 | | | INSTALL\_PARSE\_FAILED\_NO\_CERTIFICATES | 安装包没有签名 | | | INSTALL\_PARSE\_FAILED\_INCONSISTENT\_CERTIFICATES | 已安装该应用,且签名与 APK 文件不一致 | 先卸载设备上的该应用,再安装 | | INSTALL\_PARSE\_FAILED\_CERTIFICATE\_ENCODING | 解析 APK 文件时遇到 `CertificateEncodingException` | | | INSTALL\_PARSE\_FAILED\_BAD\_PACKAGE\_NAME | manifest 文件里没有或者使用了无效的包名 | | | INSTALL\_PARSE\_FAILED\_BAD\_SHARED\_USER\_ID | manifest 文件里指定了无效的共享用户 ID | | | INSTALL\_PARSE\_FAILED\_MANIFEST\_MALFORMED | 解析 manifest 文件时遇到结构性错误 | | | INSTALL\_PARSE\_FAILED\_MANIFEST\_EMPTY | 在 manifest 文件里找不到找可操作标签(instrumentation 或 application) | | | INSTALL\_FAILED\_INTERNAL\_ERROR | 因系统问题安装失败 | | | INSTALL\_FAILED\_USER\_RESTRICTED | 用户被限制安装应用 | 在开发者选项里将「USB安装」打开,如果已经打开了,那先关闭再打开。 | | INSTALL\_FAILED\_DUPLICATE\_PERMISSION | 应用尝试定义一个已经存在的权限名称 | | | INSTALL\_FAILED\_NO\_MATCHING\_ABIS | 应用包含设备的应用程序二进制接口不支持的 native code | | | INSTALL\_CANCELED\_BY\_USER | 应用安装需要在设备上确认,但未操作设备或点了取消 | 在设备上同意安装 | | INSTALL\_FAILED\_ACWF\_INCOMPATIBLE | 应用程序与设备不兼容 | | | INSTALL_FAILED_TEST_ONLY | APK 文件是使用 Android Studio 直接 RUN 编译出来的文件 | 通过 Gradle 的 assembleDebug 或 assembleRelease 重新编译,或者 Generate Signed APK | | does not contain AndroidManifest.xml | 无效的 APK 文件 | | | is not a valid zip file | 无效的 APK 文件 | | | Offline | 设备未连接成功 | 先将设备与 adb 连接成功 | | unauthorized | 设备未授权允许调试 | | | error: device not found | 没有连接成功的设备 | 先将设备与 adb 连接成功 | | protocol failure | 设备已断开连接 | 先将设备与 adb 连接成功 | | Unknown option: -s | Android 2.2 以下不支持安装到 sdcard | 不使用 `-s` 参数 | | No space left on device | 空间不足 | 清理空间 | | Permission denied ... sdcard ... | sdcard 不可用 | | | signatures do not match the previously installed version; ignoring! | 已安装该应用且签名不一致 | 先卸载设备上的该应用,再安装 | 参考:[PackageManager.java](https://github.com/android/platform_frameworks_base/blob/master/core%2Fjava%2Fandroid%2Fcontent%2Fpm%2FPackageManager.java) *`adb install` 内部原理简介* `adb install` 实际是分三步完成: 1. push apk 文件到 /data/local/tmp。 2. 调用 pm install 安装。 3. 删除 /data/local/tmp 下的对应 apk 文件。 所以,必要的时候也可以根据这个步骤,手动分步执行安装过程。 ### 卸载应用 命令: ```sh adb uninstall [-k] <packagename> ``` `<packagename>` 表示应用的包名,`-k` 参数可选,表示卸载应用但保留数据和缓存目录。 命令示例: ```sh adb uninstall com.qihoo360.mobilesafe ``` 表示卸载 360 手机卫士。 ### 清除应用数据与缓存 命令: ```sh adb shell pm clear <packagename> ``` `<packagename>` 表示应用名包,这条命令的效果相当于在设置里的应用信息界面点击了「清除缓存」和「清除数据」。 命令示例: ```sh adb shell pm clear com.qihoo360.mobilesafe ``` 表示清除 360 手机卫士的数据和缓存。 ### 查看前台 Activity 命令: ```sh adb shell dumpsys activity activities | grep mFocusedActivity ``` 输出示例: ```sh mFocusedActivity: ActivityRecord{8079d7e u0 com.cyanogenmod.trebuchet/com.android.launcher3.Launcher t42} ``` 其中的 `com.cyanogenmod.trebuchet/com.android.launcher3.Launcher` 就是当前处于前台的 Activity。 ### 查看正在运行的 Services 命令: ```sh adb shell dumpsys activity services [<packagename>] ``` `<packagename>` 参数不是必须的,指定 `<packagename>` 表示查看与某个包名相关的 Services,不指定表示查看所有 Services。 `<packagename>` 不一定要给出完整的包名,比如运行 `adb shell dumpsys activity services org.mazhuang`,那么包名 `org.mazhuang.demo1`、`org.mazhuang.demo2` 和 `org.mazhuang123` 等相关的 Services 都会列出来。 ### 查看应用详细信息 命令: ```sh adb shell dumpsys package <packagename> ``` 输出中包含很多信息,包括 Activity Resolver Table、Registered ContentProviders、包名、userId、安装后的文件资源代码等路径、版本信息、权限信息和授予状态、签名版本信息等。 `<packagename>` 表示应用包名。 输出示例: ```sh Activity Resolver Table: Non-Data Actions: android.intent.action.MAIN: 5b4cba8 org.mazhuang.guanggoo/.SplashActivity filter 5ec9dcc Action: "android.intent.action.MAIN" Category: "android.intent.category.LAUNCHER" AutoVerify=false Registered ContentProviders: org.mazhuang.guanggoo/com.tencent.bugly.beta.utils.BuglyFileProvider: Provider{7a3c394 org.mazhuang.guanggoo/com.tencent.bugly.beta.utils.BuglyFileProvider} ContentProvider Authorities: [org.mazhuang.guanggoo.fileProvider]: Provider{7a3c394 org.mazhuang.guanggoo/com.tencent.bugly.beta.utils.BuglyFileProvider} applicationInfo=ApplicationInfo{7754242 org.mazhuang.guanggoo} Key Set Manager: [org.mazhuang.guanggoo] Signing KeySets: 501 Packages: Package [org.mazhuang.guanggoo] (c1d7f): userId=10394 pkg=Package{55f714c org.mazhuang.guanggoo} codePath=/data/app/org.mazhuang.guanggoo-2 resourcePath=/data/app/org.mazhuang.guanggoo-2 legacyNativeLibraryDir=/data/app/org.mazhuang.guanggoo-2/lib primaryCpuAbi=null secondaryCpuAbi=null versionCode=74 minSdk=15 targetSdk=25 versionName=1.1.74 splits=[base] apkSigningVersion=2 applicationInfo=ApplicationInfo{7754242 org.mazhuang.guanggoo} flags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ] privateFlags=[ RESIZEABLE_ACTIVITIES ] dataDir=/data/user/0/org.mazhuang.guanggoo supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity] timeStamp=2017-10-22 23:50:53 firstInstallTime=2017-10-22 23:50:25 lastUpdateTime=2017-10-22 23:50:55 installerPackageName=com.miui.packageinstaller signatures=PackageSignatures{af09595 [53c7caa2]} installPermissionsFixed=true installStatus=1 pkgFlags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ] requested permissions: android.permission.READ_PHONE_STATE android.permission.INTERNET android.permission.ACCESS_NETWORK_STATE android.permission.ACCESS_WIFI_STATE android.permission.READ_LOGS android.permission.WRITE_EXTERNAL_STORAGE android.permission.READ_EXTERNAL_STORAGE install permissions: android.permission.INTERNET: granted=true android.permission.ACCESS_NETWORK_STATE: granted=true android.permission.ACCESS_WIFI_STATE: granted=true User 0: ceDataInode=1155675 installed=true hidden=false suspended=false stopped=true notLaunched=false enabled=0 gids=[3003] runtime permissions: android.permission.READ_EXTERNAL_STORAGE: granted=true android.permission.READ_PHONE_STATE: granted=true android.permission.WRITE_EXTERNAL_STORAGE: granted=true User 999: ceDataInode=0 installed=false hidden=false suspended=false stopped=true notLaunched=true enabled=0 gids=[3003] runtime permissions: Dexopt state: [org.mazhuang.guanggoo] Instruction Set: arm64 path: /data/app/org.mazhuang.guanggoo-2/base.apk status: /data/app/org.mazhuang.guanggoo-2/oat/arm64/base.odex [compilation_filter=speed-profile, status=kOatUpToDa te] ``` ### 查看应用安装路径 命令: ``` adb shell pm path <PACKAGE> ``` 输出应用安装路径 输出示例: ``` adb shell pm path ecarx.weather package:/data/app/ecarx.weather-1.apk ```