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

时间:2013-11-26 20:29:15

标签: android shell service adb

在设备上使用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 isms的{​​{1}}和android.app.INotificationManager的{​​{1}}。我如何使用这些信息来了解我可以对这些服务做些什么?

4 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:7)

我的第一个答案,所以我希望对你有用。

为了解释这个小谜语让我使用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的通知服务。好开心。

答案 2 :(得分:4)

简而言之

  

与服务调用命令有关的代码只是该函数的参数和位于   该功能出现在该服务的辅助文件中。这是一种语法

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的完整路径。
要知道您需要在Google上搜索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
因此,我将转到以下网站,其中google将代码放在该网站上,并从页面的左侧选择我的操作系统版本-

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后,我的完整网址将如下所示

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个位置显示为7。其他方法类似。
因此,如果我想调用第七种方法,我将输入

adb shell service call clipboard 7 

正如您可能已经看到的那样,我并没有放置callingPackage名称,因为它不是必需的。

如果该方法需要参数,则可以像本示例中所示那样传递它。
让我们假设一个方法的代码在剪贴板中为8,看起来像这样-

getDemo(String arg1, int arg2, boolean arg3)

所以我会这样称呼

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

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

提示(例如在android studio中保持打开状态),以检查执行该adb命令时发生的任何错误。

答案 3 :(得分:0)

使用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 repositorydemo.gif


请注意,由于isms服务不再具有sendText方法,因此您在isms上发送SMS的调用不再起作用。您现在可能必须使用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,...]