33 votos

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

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

Espero hacerlo usando ADB sobre USB y no estoy interesado en instalar ninguna aplicación que me ayude a hacerlo, ya que es algo que planeo hacer raramente.

Cualquier sugerencia o ayuda que me guíe en la dirección correcta será muy apreciada.

0 votos

Para quien busque enfoques más sencillos para los emuladores, vea aquí: stackoverflow.com/questions/3391160/

24voto

David Negron Puntos 971

Sí, realmente puedes hacer esto. Se ve un poco torpe cuando inspeccionas el portapapeles, pero funciona muy bien.

Primero, puedes inspeccionar el contenido actual del portapapeles con service call clipboard 1 de una cáscara de adb (o, sin desgranar primero, adb shell service call clipboard 1 ). Puede empezar en blanco inicialmente después de un reinicio, por ejemplo:

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

Puedes poner texto en el portapapeles usando service call clipboard 2 que básicamente toma 3 parámetros: dos pulgadas y la cuerda que quieres poner en el portapapeles:

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

Para ser honesto, no estoy seguro de cuáles son los dos primeros parámetros. Una respuesta sobre el desbordamiento de la pila ha sugerido que la primera int es "número de artículos en el paquete" (uno en este caso) y que la segunda es la longitud de la cuerda. 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 toma eso como algo que valga la pena.

En cualquier caso, es básicamente la creación de un objeto Parcela con 3 campos, y luego pasarlo al portapapeles. El portapapeles entonces desempaqueta el Parcela y establece el valor de la cadena pasada como el contenido del portapapeles. Puedes ver esto cuando vayas 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 se pulsa durante mucho tiempo en un campo de entrada de texto y se pulsa "Pegar" después de hacer esto, se obtendrá el texto que se estableció a través de la call service clipboard 2 línea arriba (y se verá completamente normal).

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

1 votos

Por fin puedo pegar mi clave WPA y conectarme a mi router :D. Gracias.

3 votos

@earthmeLon si usted estaba tratando de encontrar una manera fácil de copiar su clave WPA, entonces la próxima vez que usted podría encontrar que es más fácil hacer seomthing como el correo electrónico a sí mismo y copiar / pegar desde el correo electrónico, o copiar un archivo de texto que contiene en su dispositivo a través de USB, a continuación, abrir y copiar desde allí. Hay otras opciones como Teclado Wifi que te permiten escribir (o pegar) desde un PC y que aparezca en el teléfono.

4 votos

Mi clave WPA es sensible. No debe ser transmitida por ninguna red no local NUNCA. Gracias por las sugerencias @GAThrawn. Encontraré más uso para esta funcionalidad eventualmente :D

21voto

JacquesB Puntos 19878

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

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

como un bono adicional, aquí está mi script ( editado 2015-04-24 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"

0 votos

La razón por la que es necesario escapar doblemente la cadena es que hay dos shells: tu shell, y el shell adb . Sin embargo, sospecho que esto fallará para otros caracteres que tienen un significado especial en el shell, como el carácter ampersand .

0 votos

En realidad sería tarea de adb shell hacer correctamente este escape, pero al parecer no lo hace completamente. En mi versión (1.0.31) el espacio-escapado usado arriba no es necesario, pero todo tipo de caracteres especiales necesitarían ser escapados (pero es imposible hacerlo de forma fiable).

0 votos

Una mejor manera de manejar caracteres especiales sería canalizar a través de stdin, algo como: echo "$TEXT" | adb shell xargs -0 input text Que debe manejar cualquier texto, excepto \0 (NUL). Lamentablemente, las versiones antiguas de adb no reenvían stdin a un comando especificado en la línea de comandos de adb. Esto se ha solucionado en las nuevas versiones de adb, pero necesita Android N para funcionar .

5voto

CHK Puntos 117

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

Este script está mejorado para escapar de los caracteres especiales para evitar confundir al shell de Android con ellos. Esto debería permitir que cualquier cadena sea enviada sin cambios. Para evitar que el read de interpretar un (al final) de la barra invertida, he añadido -r.

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

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

Aquí está el 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"

3voto

cbenn95 Puntos 45

He probado y buscado en Google un poco y parece que el servicio de llamada al portapapeles ha dejado de funcionar en los nuevos Androids, a mí me falló en una versión 4.4.4 de Android. Es decir, se necesita 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 que lo compiles tú mismo. Una vez instalada, puedes comunicarte con ella usando comandos de transmisión (la aplicación te dirá los comandos exactos). La aplicación no requiere Root.

0 votos

Como no sabemos qué su propósito es: ¿podría por favor editar tu post e incluir qué hace esa aplicación y cómo se supone que hay que usarla? La gente ya empieza a marcar tu post como "no es una respuesta", ya que obviamente no entienden lo que quieres decir. Gracias de antemano.

0 votos

Clipper me funcionó mejor que usar 'adb shell input text'. Incluso mejor que el script de Python AdbPaste github.com/gcb/AdbPaste para envolver 'adb shell input text'. He mejorado clipper para soportar un parámetro de archivo, por lo que ahora puedo enviar varias páginas en el portapapeles en sólo un segundo o dos. Código mejorado aquí: github.com/RoundSparrow/clipper

3voto

CHK Puntos 117

Otro script que utiliza adb shell input para enviar caracteres se puede encontrar aquí: https://github.com/gcb/AdbPaste

Este es un script que puede ser clonado desde github, o también descargado y ejecutado directamente:

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

PreguntAndroid.com

PreguntAndroid es una comunidad de usuarios de Android en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X