Android 必知必会 - 使用 ADB 操作 Clipboard

关键词:service callclipboardUnknown package

手里一个项目需要执行个骚操作,其中有一个步骤是使用 ADB 来操作 Clipboard(粘贴板),搜索许久发现直接操作并不可行,确切的说是在 Android API >=11 时是不可行的。

操作环境:macOS Sierra 10.12.6 + iTerm2,一些命令可能会因系统等不同而略有不同,请自行测试。

前置知识点

首先了解下 ADB Shell 中的 service ,在命令行里执行能看到如下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ adb shell
$ service
Usage: service [-h|-?]
service list
service check SERVICE
service call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR ] ...
Options:
i32: Write the 32-bit integer N into the send parcel.
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.
s16: Write the UTF-16 string STR into the send parcel.
$ service list | grep clipboard
# If use windows system, use findstr:
# service list | findstr "clipboard"
63 clipboard: [android.content.IClipboard]

下面找 CODE ,查看 Clipboard 的源码:

1
2
3
4
5
6
7
8
9
10
11
12
// API < 11
static final int TRANSACTION_getClipboardText 1
static final int TRANSACTION_hasClipboardText 3
static final int TRANSACTION_setClipboardText 2
// API >= 11
static final int TRANSACTION_setPrimaryClip = 1
static final int TRANSACTION_getPrimaryClip = 2
static final int TRANSACTION_getPrimaryClipDescription = 3
static final int TRANSACTION_hasPrimaryClip = 4
static final int TRANSACTION_addPrimaryClipChangedListener = 5
static final int TRANSACTION_removePrimaryClipChangedListener = 6
static final int TRANSACTION_hasClipboardText = 7

分析

Clipboard 源码指出这些事务需要什么参数。TRANSACTION_setPrimaryClip 需要一个 ClipData,它不是一个 i32 或 s16,因此与服务调用不兼容。 更重要的是,这些事务需要调用包名称作为参数,剪贴板服务验证指定的包名称与调用的 uid 相匹配。 当使用adb shell 时,调用的 uid 是 UID_ROOT 或者 UID_SHELL,它们都不拥有任何包,所以没有办法通过这个检查。 简而言之,新的剪贴板服务不能以这种方式使用。

所以在 API >= 11 的系统上使用 service call clipboard [1 | 2 | 3] [i32 N | i64 N | f N | d N | s16 STR ] 已经不可行了。

所以无论命令正确与否,都会提示 Unknown package

1
2
3
4
5
$ service call clipboard 2 s16 "abc"
Result: Parcel(
0x00000000: fffffffd 00000013 006e0055 006e006b '........U.n.k.n.'
0x00000010: 0077006f 0020006e 00610070 006b0063 'o.w.n. .p.a.c.k.'
0x00000020: 00670061 00200065 00620061 00000063 'a.g.e. .a.b.c...')

总结

就 Android 目前的各版本系统市场占有率而言,使用 ADB 操作 Clipboard 是一个不可行的方案了

参考:

有什么建议或者问题可以随时联系我,共同探讨学习: