Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
357 views
in Technique[技术] by (71.8m points)

android - Set clipboard text via adb shell as of API level 11

Before API level 11, it was possible to set the content of the clipboard by using the service program on the 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.

There were three integer codes to define the methods:

1 TRANSACTION_getClipboardText
2 TRANSACTION_setClipboardText
3 TRANSACTION_hasClipboardText

For instance this command

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

set the clipboard's content to "Hello Android!". As of API level 11 the listed methods are deprecated and the new ones take ClipData as an argument. How do you set the clipboard content now via adb shell?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You've asked two different questions here. The service calls are not related to the API functions.

Android is in general overly-aggressive about marking APIs as deprecated. In this case, it only means that there are new functions with more functionality. The functionality of getText(), hasText(), and setText() still exists and those functions will continue to work, but they are now implemented as trivial wrappers around the newer functions.

As far as the service calls go, those are an internal implementation detail and as you've noticed are not guaranteed to work across Android versions. If you peer into the Android source code, you'll find these transactions currently defined:

TRANSACTION_setPrimaryClip = 1
TRANSACTION_getPrimaryClip = 2
TRANSACTION_getPrimaryClipDescription = 3
TRANSACTION_hasPrimaryClip = 4
TRANSACTION_addPrimaryClipChangedListener = 5
TRANSACTION_removePrimaryClipChangedListener = 6
TRANSACTION_hasClipboardText = 7

The source code also indicates what parameters these transactions require. Unfortunately, TRANSACTION_setPrimaryClip requires a ClipData, which is not an i32 or an s16 and thus is not compatible with service call. We have bigger problems than that however; these transactions require the calling package name as a parameter, and the clipboard service validates that the specified package name matches the calling uid. When using the adb shell, the calling uid is either UID_ROOT or UID_SHELL, neither of which owns any packages, so there is no way to pass that check. Simply put, the new clipboard service cannot be used this way.

What can you do about all this? You can create your own service for manipulating the clipboard from the commandline and install it onto your device. I don't know if there's any way to extend service call, but you can use am startservice as a suitable replacement. If you've created and installed that custom clipboard service, then you could invoke it as:

am startservice -a MySetClipboard -e text "clipboard text"

The code to implement this service could look like this:

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;
    }
}

The service should have an intent-filter that declares it capable of handling the MySetClipboard intent action.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...