¿Es posible escribir en el portapapeles de un dispositivo usando ADB?

26

Estoy interesado en aprender a escribir (y si es posible, leer desde) el portapapeles de un dispositivo Android rooteado.

Espero hacerlo usando ADB a través de USB y no estoy interesado en instalar ninguna aplicación para ayudarme a hacer esto, ya que esto es algo que planeo hacer raramente.

Cualquier sugerencia o ayuda para guiarme en la dirección correcta sería muy apreciada

earthmeLon
fuente
Para cualquiera que esté buscando enfoques más fáciles para los emuladores, consulte aquí: stackoverflow.com/questions/3391160/…
Mygod

Respuestas:

21

Sí, en realidad puedes hacer esto. Es un poco turbio cuando inspeccionas el portapapeles, pero funciona bien.

En primer lugar, puede inspeccionar el contenido actual del portapapeles service call clipboard 1desde un shell adb (o, sin bombardear primero adb shell service call clipboard 1). Puede comenzar inicialmente en blanco después de un reinicio, por ejemplo:

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

Puede poner texto en el portapapeles utilizando service call clipboard 2, que básicamente toma 3 parámetros: dos entradas y la cadena que desea poner en el portapapeles:

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

Para ser sincero, no estoy seguro de cuáles son los dos primeros parámetros. Una respuesta en Stack Overflow ha sugerido que el primer int es "número de elementos en la parcela" (uno en este caso) y que el segundo es la longitud de la cadena. Sin embargo, he usado 0 para el segundo parámetro y funciona bien, y no puedo encontrar ninguna documentación que coincida con esta función en particular ... así que tómalo por lo que vale.

En cualquier caso, básicamente se trata de crear un objeto Parcel con 3 campos y luego pasarlo al portapapeles. Luego, el portapapeles desempaqueta la parcela y establece el valor de cadena que se pasa como contenido del portapapeles. Puede ver esto cuando vaya a recuperar el valor después:

# 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                   '........        ')
#

Del mismo modo, si presiona prolongadamente en un campo de entrada de texto y presiona "Pegar" después de hacer esto, obtendrá el texto que se configuró a través de la call service clipboard 2línea anterior (y se verá completamente normal).

(Los ejemplos anteriores provienen de mi HTC EVO, que ejecuta CyanogenMod 7)

eldarerathis
fuente
1
Finalmente puedo pegar mi clave WPA y conectarme a mi enrutador: D. Gracias.
earthmeLon
3
@earthmeLon si solo estaba tratando de encontrar una manera fácil de copiar su clave WPA, entonces la próxima vez podría resultarle más fácil hacer algo como enviarse un correo electrónico y copiar / pegar desde un correo electrónico, o copiar un archivo de texto que lo contenga en su dispositivo a través de USB, luego abra y copie desde allí. Hay otras opciones como el Teclado Wifi que le permite escribir (o pegar) desde una PC y que aparezca en el teléfono.
GAThrawn
44
Mi clave WPA es sensible. No debe transmitirse por ninguna red no local NUNCA. Gracias por las sugerencias @GAThrawn. Eventualmente encontraré más uso para esta funcionalidad: D
earthmeLon
66
Me sale '........U.n.k.n.' 'o.w.n. .p.a.c.k.' 'a.g.e. ..... ')al hacercall service clipboard 2
cprcrack
3
En caso de que necesite copiar su contraseña o cualquier texto en un campo de texto en Android, también podría "abd ingresar el texto de entrada 'String'" - He renunciado en el portapapeles ...
Philippe
14

Utilicé esta metodología, y funcionó bien en 4.x, pero falló en lollipop. Mientras buscaba una solución alternativa, encontré esto: /programming/3391160/paste-text-on-android-emulator

no es exactamente como lo quería, pero para mí, la mayoría de las veces que quiero copiar texto al portapapeles es porque quiero pegarlo en el campo de contraseña.

Como un bono adicional, aquí está mi script ( editado el 24/04/2015 para permitir espacios en el texto ):

#!/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"
galets
fuente
La razón por la que necesita escapar doblemente de la cadena es que hay dos shells: su shell y el shell adb . Sin embargo, sospecho que esto fallará para otros personajes que tienen un significado especial en el caparazón, como el ampersand .
Dan Dascalescu
En realidad, sería la tarea de adb shell hacer este escape correctamente, pero aparentemente no lo hace por completo. En mi versión (1.0.31), el escape de espacio utilizado anteriormente no es necesario, pero todo tipo de caracteres especiales necesitarían escapar (pero es imposible hacerlo de manera confiable).
Matthijs Kooijman
Una mejor manera de manejar caracteres especiales sería canalizar a través de stdin, algo así como: echo "$TEXT" | adb shell xargs -0 input textque debe manejar cualquier texto, excepto los caracteres \ 0 (NUL). Desafortunadamente, las versiones anteriores de adb no reenvían stdin a un comando especificado en la línea de comandos de adb. Esto se soluciona en las nuevas versiones de adb, pero necesita Android N para funcionar .
Matthijs Kooijman
En cuanto al escape de espacio, aparentemente esto es necesario para el inputcomando en el dispositivo Android, no para el shell utilizado por adb shell. Además, solo es necesario para SDK versión 22 e inferior (Lollipop e inferior, creo) de acuerdo con esta respuesta .
Matthijs Kooijman
4

Aquí hay una versión mejorada del guión de los galets anteriores. Al igual que con ese script, no escribe en el portapapeles, sino que envía información al campo de entrada actualmente enfocado, que a menudo es lo que desea de todos modos.

Este script se ha mejorado para escapar de caracteres especiales para evitar confundir el shell de Android con ellos. Esto debería permitir que cualquier cadena se envíe sin cambios. Para evitar que el readcomando interprete una barra diagonal inversa (final), agregué -r allí.

Esto se probó utilizando la siguiente lista de caracteres especiales:

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

Aquí está el guión:

#!/bin/bash
# Send text to android device using adb, emulating keyboard input.
# Based on a script from /android//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 /programming//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"
Matthijs Kooijman
fuente
3

Lo intenté y busqué en Google un poco y parece que el enfoque del portapapeles call-service dejó de funcionar en los androides más nuevos, me falló en una versión 4.4.4 de Android. Es decir, necesitará una aplicación para obtener acceso al portapapeles (lectura y escritura) desde adb-shell. Yo uso clipper de majido en github . El apk también está alojado, por lo que no es necesario compilarlo usted mismo. Una vez instalado, puede comunicarse con él mediante comandos de difusión (la aplicación le indicará los comandos exactos). La aplicación no requiere root.

Sascha N.
fuente
Como no sabemos cuál es su propósito: ¿podría editar su publicación e incluir lo que hace esa aplicación y cómo se supone que debe usarla? Las personas ya comienzan a marcar su publicación como "no es una respuesta", ya que obviamente pierden el punto que desea hacer. ¡Gracias por adelantado!
Izzy
Clipper funcionó mejor para mí que usar 'adb shell input text'. Incluso mejor que el script de Python AdbPaste github.com/gcb/AdbPaste para envolver el 'texto de entrada del shell adb'. He mejorado Clipper para admitir un parámetro de archivo, por lo que ahora puedo enviar varias páginas al portapapeles en solo un segundo o dos. Código mejorado aquí: github.com/RoundSparrow/clipper
RoundSparrow hilltx
0

adb shell inputPuede encontrar otro script que utiliza para enviar caracteres aquí: https://github.com/gcb/AdbPaste

Este es un script de Python que se puede clonar desde github, o también se puede descargar y ejecutar directamente:

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