在哪里可以找到有关 Android 的“服务调用”shell 命令的信息?

Posted

技术标签:

【中文标题】在哪里可以找到有关 Android 的“服务调用”shell 命令的信息?【英文标题】:Where to find info on Android's "service call" shell command? 【发布时间】:2013-12-12 04:49:30 【问题描述】:

在设备上使用adb shell 或终端模拟器,输入它会清除所有通知(需要su

service call notification 1

这将发送一条短信(不需要su

service call isms 5 s16 "PhoneNumber" i32 0 i32 0 s16 "BodyText"

在哪里可以了解有关service call 的更多信息?我找到了this question 并感谢答案对一切含义的细分。但是我在哪里可以找到关于 notification 2 可能试图调用的方法的信息?

运行service call 不完整,并打印了这个用法:

Usage: service [-h|-?]
       service list
       service check SERVICE
       service call SERVICE CODE [i32 INT | s16 STR] ...
Options:
   i32: Write the integer INT into the send parcel.
   s16: Write the UTF-16 string STR into the send parcel.

我运行了service list,它为我的设备返回了 78 项服务,包括 ismsnotification,并且对于大多数服务,将打印似乎是命名空间的内容(com.android.internal.telephony.ISms 用于 ismsandroid.app.INotificationManager对于notification)。我如何使用这些信息来了解我可以使用这些服务做什么?

【问题讨论】:

也在android.stackexchange.com/q/57778/1302询问 是的,由我。我不确定哪个社区能够更好地回答我的问题。我认为两个社区都可以从中受益。 【参考方案1】:

简而言之

与服务调用命令相关的代码只是函数的参数和顺序 该函数出现在该服务的aidl文件中。这是一个语法

service call <your_service_name> <number at which the function appears in your_service_name.aidl> <type of the argument like i32 or i64> <argument>

详细说明 我遇到了很多问题要了解它,因此我将在剪贴板服务的帮助下分享解决方案。 首先您需要了解您感兴趣的服务 - 为此,您需要通过键入来查找特定 android 系统的所有服务

adb shell service list

这就是你会得到的-

.
.
.
59  ethernet: [android.net.IEthernetManager]
60  wifip2p: [android.net.wifi.p2p.IWifiP2pManager]
61  rttmanager: [android.net.wifi.IRttManager]
62  wifiscanner: [android.net.wifi.IWifiScanner]
63  wifi: [android.net.wifi.IWifiManager]
64  overlay: [android.content.om.IOverlayManager]
65  netpolicy: [android.net.INetworkPolicyManager]
66  netstats: [android.net.INetworkStatsService]
67  network_score: [android.net.INetworkScoreService]
68  textservices: [com.android.internal.textservice.ITextServicesManager]
69  network_management: [android.os.INetworkManagementService]
70  clipboard: [android.content.IClipboard]
71  statusbar: [com.android.internal.statusbar.IStatusBarService]
.
.
.

因为我对剪贴板服务感兴趣,所以它看起来是这样的

70  clipboard: [android.content.IClipboard]

所以从这里我们可以总结出服务名是剪贴板服务,包路径是android.content.IClipboard

那你需要知道IClipboard.aidl所在的完整路径。 要知道您需要在谷歌上搜索 IClipboard.aidl。 您需要在结果中从 android.googlesource.com 网站中查找某些内容,例如我的情况-

https://android.googlesource.com/platform/frameworks/base.git/+/android-4.2.2_r1/core/java/android/content/IClipboard.aidl

所以在 +/android-4.2.2_r1 之后是你的路径所在。让路径为 path_of_clipboard.aidl=

/core/java/android/content/IClipboard.aidl

由于这些服务调用代码依赖于 android 系统,因此您需要知道您的 android 操作系统名称- 就我而言,它是 8.1.0 所以我会去下面的网站,谷歌在那里放代码,然后从页面的左侧选择我的操作系统版本-

https://android.googlesource.com/platform/frameworks/base/

就我而言,它是 android-8.1.0_r50。这里 r50 并不重要。您可以选择任何修订。现在我将点击链接,然后我的网址将如下所示

https://android.googlesource.com/platform/frameworks/base/+/android-8.1.0_r51

然后在添加 path_of_clipboard.aidl 之后,我的完整 url 会是这样的

https://android.googlesource.com/platform/frameworks/base/+/android-8.1.0_r51/core/java/android/content/IClipboard.aidl

这里会有很多接口中的方法。就像我的情况

    void setPrimaryClip(in ClipData clip, String callingPackage);
    ClipData getPrimaryClip(String pkg);
    ClipDescription getPrimaryClipDescription(String callingPackage);
    boolean hasPrimaryClip(String callingPackage);
    void addPrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener,
            String callingPackage);
    void removePrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener);
    /**
     * Returns true if the clipboard contains text; false otherwise.
     */
    boolean hasClipboardText(String callingPackage);

因此,第一个方法(即 setPrimaryClip)的代码将是 1,因为它出现在第一位,而最后一个方法(即 hasClipboardText)的代码将是 7,因为它出现在aidl 文件中的第七位。对于其他方法也是如此。 所以如果我想调用第七个方法,我会输入

adb shell service call clipboard 7 

您可能已经看到,我没有输入调用包名称,因为它不是必需的。

如果方法需要参数,那么您可以像本例所示那样传递它。让我们假设一个方法,其代码为 8 在剪贴板中,如下所示 -

getDemo(String arg1, int arg2, boolean arg3)

所以我会这样称呼它

adb shell call clipboard 8 s16 "first_argument" i32 12 i32 1

这里 i32 代表 32 位整数,s16 代表字符串。我们甚至可以将布尔值作为整数传递,如示例所示。 在布尔整数中,1 代表真,0 代表假。Source

提示 保持 logcat 处于打开状态(就像在 android studio 中一样)以检查执行该 adb 命令时发生的任何错误。

【讨论】:

“在我的例子中是 android-8.1.0_r50”:你是指单个设备上的 Android 版本,还是 Gradle 配置中的 compileSdkVersion? r50 并不重要,因为它们不会在版本之间的接口文件中引入新功能。我已经编辑过了。 很高兴知道,顺便说一句,答案很好。但是,我的问题是:我们是在寻找已安装的设备 Android OS 版本,还是编译应用程序的版本? (即compileSdkVersion) 我们正在考虑设备上安装的版本,因为与应用关联的版本对我来说没有任何意义。 完美,感谢您的澄清。我不确定发出调用的应用程序的编译版本是否改变了 shell 命令的解释方式。 (即使用 Pie SDK 28 编译的应用程序,在 Oreo 操作系统上运行)【参考方案2】:

这是我关于Calling Android services from ADB shell 的帖子。它包括一个小 bash 脚本,我使用该脚本为我的特定设备自动下载正确版本的服务源代码,然后对其进行解析以找出所有方法的事务代码。

【讨论】:

这真的是答案!太糟糕了,我花了 2 年时间才找到你的剧本!众所周知,每个服务调用在很大程度上都依赖于 AOS/API,调用编号越低,越有可能跨 AOS 版本兼容。对于更大的数字,例如service call phone 87 i32 0 i32 1(将网络设置为仅使用 2G GSM)很可能会在所有其他设备上失败,而不是预期。【参考方案3】:

我在这里的第一个答案,希望对你有用。

为了解释这个小谜语,让我使用 android 4.3.1。 This 链接在您的情况下可能是必不可少的。将 java 代码向下滚动到第 669 行。等待您的 TRANSACTION 块与 com.android.internal.telephony.ISms 服务严格相关,并且可能您的答案是您可以做更多的事情。

在您的情况下,您正在调用 TRANSACTION_sendText。说明在第 673 行,您可以在其中找到

static final int TRANSACTION_sendText = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);

代码的最后一部分由数字“4”组成。每个 TRANSACTION 编号 + 1 = 正确的编号。这就是为什么service call isms 5 负责sendText 而不是sendMultipartText

相同的规则适用于所有服务。

我相信您现在已经了解了如何检查 TRANSACTIONs 以获取通知服务。好开心。

【讨论】:

您链接到的 java 文件不是官方源代码树的一部分。它是从 AIDL 文件生成的 - android.googlesource.com/platform/frameworks/base/+/… 。我发现它也更容易解析 @AlexP 没抓住重点——您需要执行此操作的信息是 in 编译的文件。源 AIDL 文件根本没有事务编号,因为它们是在编译时生成的。 @GlennMaynard,我没有遗漏任何东西。我完全有能力自己计算文本文件中的行数 - 这是 AIDL 编译过程的相关(查找交易编号)部分的全部范围。 更容易计算函数的数量(每页相隔一页——你不计算行,可能有几十行),希望你以同样的方式在心理上编译文件,而不是搜索并在那里看到实际的常数值?抱歉,如果这感觉有点做作。【参考方案4】:

使用service call notification 1 等并不安全,因为它可能在您运行它的任何设备上执行完全不同的操作。

您可以改用android-svc。例如。拨打号码(不打电话):

android-svc --adb call 'phone.dial("555-0199")'

它还为您提供有关数据类型的信息。例如

android-svc --adb method-signature 'phone.dial'

将打印:

void dial(String number);

它还可以首先列出给定服务的方法...

此 gif 取自 the repository:


请注意,在最新版本的 Android 中,您发送 SMS 的 isms 调用将不再起作用,因为 isms 服务不再具有 sendText 方法。你现在可能不得不使用sendTextForSubscriber,因为它需要更多的参数,所以更难调用。


另外,直接回答您的问题在哪里可以找到有关 Android 的“服务调用”shell 命令的信息?: Look at the source code.

Usage: service [-h|-?]
       service list
       service check SERVICE
       service call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR | null | fd f | nfd n | afd f ] ...
Options:
   i32: Write the 32-bit integer N into the send parcel.
   s16: Write the UTF-16 string STR into the send parcel.
自 Android 6 起可用:
   i64: Write the 64-bit integer N into the send parcel.
   f:   Write the 32-bit single-precision number N into the send parcel.
   d:   Write the 64-bit double-precision number N into the send parcel.
自 Android 11 起可用:
  null: Write a null binder into the send parcel.
    fd: Write a file descriptor for the file f to the send parcel.
   nfd: Write file descriptor n to the send parcel.
   afd: Write an ashmem file descriptor for a region containing the data from file f to the send parcel.
一直可用的隐藏选项:
intent: Write and Intent int the send parcel. ARGS can be action=STR data=STR type=STR launchFlags=INT component=STR categories=STR[,STR,...]

【讨论】:

以上是关于在哪里可以找到有关 Android 的“服务调用”shell 命令的信息?的主要内容,如果未能解决你的问题,请参考以下文章

哪里可以找到安卓崩溃历史

在哪里可以找到有关 openssh/sftp-server 协议的文档?

在哪里可以找到有关内核设备树 pinctrl 参数的文档?

在哪里可以找到有关 Firebase 云消息传递可用声音的文档?

在哪里可以找到有关 raspberry pi 3 外围设备的文档?

在哪里可以找到有关为 SQL Server Management Studio 创建插件的信息? [关闭]