Android 从API级别11开始,通过adb外壳设置剪贴板文本

Android 从API级别11开始,通过adb外壳设置剪贴板文本,android,api,adb,clipboard,Android,Api,Adb,Clipboard,在API级别11之前,可以使用adb shell上的服务程序设置剪贴板的内容: 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. 有三个整数代码用于定义方法: 1 TRANSACTION_getClipbo

在API级别11之前,可以使用
adb shell上的
服务
程序设置剪贴板的内容:

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.
有三个整数代码用于定义方法:

1 TRANSACTION_getClipboardText
2 TRANSACTION_setClipboardText
3 TRANSACTION_hasClipboardText
例如,这个命令

$ adb shell service call clipboard 2 i32 1 i32 1 s16 "Hello Android!"

将剪贴板的内容设置为
“Hello Android!”
。从API级别11开始,列出的方法是,新方法作为参数。您现在如何通过adb shell设置剪贴板内容?

您在这里提出了两个不同的问题。服务调用与API函数无关

Android通常过于激进地将API标记为不推荐的API。在这种情况下,这只意味着有更多功能的新功能。
getText()
hasText()
setText()
的功能仍然存在,并且这些函数将继续工作,但它们现在被实现为新函数的简单包装器

就服务调用而言,这些都是内部实现细节,正如您所注意到的,并不保证在Android版本中工作。如果您查看Android,您会发现当前定义了以下事务:

TRANSACTION_setPrimaryClip = 1
TRANSACTION_getPrimaryClip = 2
TRANSACTION_getPrimaryClipDescription = 3
TRANSACTION_hasPrimaryClip = 4
TRANSACTION_addPrimaryClipChangedListener = 5
TRANSACTION_removePrimaryClipChangedListener = 6
TRANSACTION_hasClipboardText = 7
源代码还指示这些事务需要哪些参数。不幸的是,事务\u setPrimaryClip需要
ClipData
,它不是i32或s16,因此与
服务调用不兼容。然而,我们还有更大的问题;这些事务需要调用包名称作为参数,剪贴板服务验证指定的包名称是否与调用uid匹配。当使用adb外壳时,调用的uid是uid_ROOT或uid_外壳,两者都不拥有任何包,因此无法通过该检查。简单地说,新的剪贴板服务不能以这种方式使用

你能做些什么?您可以从命令行创建自己的用于操作剪贴板的服务,并将其安装到设备上。我不知道是否有办法延长
服务呼叫
,但您可以使用
am startservice
作为合适的替代品。如果您已经创建并安装了该自定义剪贴板服务,则可以通过以下方式调用它:

am startservice -a MySetClipboard -e text "clipboard text"
实现此服务的代码可能如下所示:

public MyService extends Service {
    public int onStartCommand(Intent intent, int flags, int startId) {
        String text = intent.getStringExtra("text");
        ClipboardManager.setText(text);
        stopSelf();
        return START_NOT_STICKY;
    }
}

服务应该有一个意图过滤器,声明它能够处理
MySetClipboard
intent操作。

可以以不明显的方式检索剪贴板内容。首先确定用户ID(通过查看
/data/data/
adb shell ps|grep moz
),然后使用
su
更改用户:
adb shell su u0_99服务调用剪贴板2 s16 org.mozilla.firefox_beta
。这将返回一个丑陋的包裹(带有UTF-16?)。由于您提到的原因,我还没有尝试设置一些内容。这是一个很好的观点-如果您在设备上具有root访问权限,您可以使用
su
解决uid问题。但是,使用
服务调用
命令仍然无法构造
ClipData
。对此感兴趣的人最好安装自己的服务并调用它。这是微不足道的,我在回答问题时写了一个,并包含了源代码,这就证明了这一点。我创建了这样一个服务,因为它运行良好,所以我将它放在GitHub上,以便其他人可以使用:。