26

I am interested in learning how to write to (and if possible, read from) a rooted Android device's clipboard.

I hope to do so using ADB over USB and I am not interested in installing any apps to help me do this, as this is something I plan on rarely doing.

Any suggestions or help guiding me in the right direction would be greatly appreciated.

20

Yes, you actually can do this. It's kind of kludgy looking when you inspect the clipboard, but it works just fine.

First off, you can inspect the current clipboard contents with service call clipboard 1 from an adb shell (or, without shelling in first, adb shell service call clipboard 1). It may start out initially blank after a reboot, for example:

# service call clipboard 1
Result: Parcel(
  0x00000000: 00000000 00000001 00000000 00000000 '................'
  0x00000010: 00000000 00000000                   '........        ')
#

You can put text into the clipboard using service call clipboard 2, which basically takes 3 parameters - two ints and the string you want to put on the clipboard:

# service call clipboard 2 i32 1 i32 0 s16 "Hi there"
Result: Parcel(00000000    '....')

To be honest, I'm not sure what the first two parameters are. One answer on Stack Overflow has suggested the first int is "number of items in the parcel" (one in this case) and that the second is the length of the string. However, I've used 0 for the second parameter and it works fine, and I can't find any documentation that matches up with this particular function...so take that for what it's worth.

In any case, it's basically creating a Parcel object with 3 fields, then passing it into the clipboard. The clipboard then unpacks the Parcel and sets the string value passed in as the clipboard's contents. You can see this when you go to retrieve the value afterwards:

# service call clipboard 1
Result: Parcel(
  0x00000000: 00000000 00000001 00000000 00000008 '................'
  0x00000010: 00690048 00740020 00650068 00650072 'H.i. .t.h.e.r.e.'
  0x00000020: 00000000 00000000                   '........        ')
#

Similarly, if you long-press on a text entry field and hit "Paste" after doing this, you will get the text that was set via the call service clipboard 2 line above (and it will look completely normal).

(The above examples come from my HTC EVO, running CyanogenMod 7)

  • 1
    I can finally paste my WPA key and connect to my router :D. Thank you. – earthmeLon Feb 20 '12 at 22:50
  • 3
    @earthmeLon if you were just trying to find an easy way to copy your WPA key, then next time you might find it easier to do seomthing like email it to yourself and copy/paste from email, or copy a text file containing it onto your device over USB, then open and copy from there. There are other options like Wifi Keyboard that let you type (or paste) from a PC and have it appear on the phone. – GAThrawn Feb 21 '12 at 10:47
  • 4
    My WPA key is sensitive. It should not be broadcast over any non-local network EVER. Thanks for the suggestions @GAThrawn. I will find more use for this functionality eventually :D – earthmeLon Feb 21 '12 at 18:10
  • 6
    I get '........U.n.k.n.' 'o.w.n. .p.a.c.k.' 'a.g.e. ..... ') when making call service clipboard 2 – cprcrack May 17 '14 at 11:23
  • 3
    In case you need to copy your password or any text into a textfield on android you could also " abd shell input text 'String' " - I have given up on the clipboard... – Philippe Jun 16 '16 at 23:35
12

I used this methodology, and it worked fine in 4.x, but failed for me in lollipop. While looking for alternative solution, I found this: https://stackoverflow.com/questions/3391160/paste-text-on-android-emulator

it is not exactly as you wanted it, but for myself, most time I want to copy text to clipboard is because I want to paste it into password field.

as an additional bonus, here's my script (edited 2015-04-24 to allow spaces in text):

#!/bin/bash

if [[ "$1" != "" ]]
then
    TEXT=$1
else
    read -s -p "Enter text you want to insert: " TEXT
fi

ESCAPED_TEXT=`echo $TEXT | sed "s/\s/\%s/g"`
adb shell input text "$ESCAPED_TEXT"
  • The reason you need to doubly-escape the string is that there are two shells: your shell, and the adb shell. However, I suspect this will fail for other characters that have special meaning in the shell, like the ampersand. – Dan Dascalescu Dec 11 '15 at 2:00
  • It would actually be the task of adb shell to properly do this escaping, but apparently it doesn't completely. On my version (1.0.31) the space-escaping used above is not needed, but all kinds of special characters would need escaping (but it is impossible to do this reliably). – Matthijs Kooijman Jun 12 '17 at 14:14
  • A better way to handle special characters would be to pipe through stdin, something like: echo "$TEXT" | adb shell xargs -0 input text Which should handle any text, except for \0 (NUL) characters. Unfortunately, older adb versions do not forward stdin to a command specified on the adb commandline. This is fixed in newer adb versions, but it needs Android N to work. – Matthijs Kooijman Jun 12 '17 at 14:14
  • As for the space escaping, this is apparently needed for the input command on the Android device, not for the shell used by adb shell. Also, it is only needed for SDK version 22 and below (Lollipop and below, I believe) according to this answer. – Matthijs Kooijman Jun 12 '17 at 14:25
4

Here's an improved version of the script by galets above. As with that script, it does not write to the clipboard, but sends input to the currently focused input field, which is often what you want anyway.

This script is improved to escape special characters to prevent confusing the Android shell with them. This should allow any string to be sent unchanged. To prevent the read command from interpreting a (trailing) backslash, I added -r there.

This was tested using the following list of special characters:

./adb-send-string ' \`~!@#$%^&*()-_=+[{]}|;:",<.>/?'\'

Here's the script:

#!/bin/bash
# Send text to android device using adb, emulating keyboard input.
# Based on a script from https://android.stackexchange.com/a/105881/223695
# extended to support special characters

if [[ "$1" != "" ]]
then
    TEXT="$1"
else
    read -s -r -p "Enter text you want to insert: " TEXT
fi

escape() {
    # Encapsulate the string in $'', which enables interpretation of
    # \xnn escapes in the string. This is not POSIX-sh, but an extension
    # documented by bash and also supported by the Android sh.
    echo -n "$'"

    # Process each character in $1 one by one
    for (( i=0 ; i<${#1}; i++ )); do
        # Extract the i'th character
        C="${1:$i:1}"
        if [ "$C" = ' ' ]; then
            # Encode spaces as %s, which is needed for Android's
            # "input text" command below 6.0 Marshmellow
            # See https://stackoverflow.com/documentation/android/9408/adb-shell/3958/send-text-key-pressed-and-touch-events-to-android-device-via-adb
            echo -n '%s'
        else
            # Encode everything else as \xnn, to prevent them from being
            # interpreted by the Android shell
            printf '\\x%02x' "'$C"
        fi
    done
    # Terminate the $''
    echo -n "'"
}

ESCAPED_TEXT=`escape "$TEXT"`
adb shell input text "$ESCAPED_TEXT"
3

I have tried and googled a bit and it seems the call-service-clipboard-approach stopped working in newer androids, it failed for me on a 4.4.4 version Android. I.e. you will need an app to get clipboard access (read and write) from adb-shell. I use clipper from majido on github. The apk is hosted as well, so no need to compile it yourself. When installed you can can comunicate to it using broadcast commands (the app will tell you the exact commands). App does not require root.

  • As we don't know what your purpose is: could you please edit your post and include what that app does, and how one is supposed to use it? People already start flagging your post as "not an answer", as they obviously miss the point you want to make. Thanks in advance! – Izzy Jan 5 '17 at 22:57
  • clipper worked better for me than using 'adb shell input text'. Even better than the Python script AdbPaste github.com/gcb/AdbPaste to wrap 'adb shell input text'. I enhanced clipper to support a file parameter, so I can now send multiple-pages into the clipboard in just a second or two. Enhanced code here: github.com/RoundSparrow/clipper – RoundSparrow hilltx May 25 '17 at 2:20
0

Another script that uses adb shell input to send characters can be found here: https://github.com/gcb/AdbPaste

This is a Python script that can be cloned from github, or also directly downloaded and run:

$ wget https://github.com/gcb/AdbPaste/raw/master/AdbPaste.py
$ chmod a+x AdbPaste.py
$ ./AdbPaste.py "some text to paste"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.