É possível gravar na área de transferência de um dispositivo usando o ADB?

26

Estou interessado em aprender a escrever (e, se possível, ler a partir de) a área de transferência de um dispositivo Android com raiz.

Espero fazer isso usando o ADB sobre USB e não estou interessado em instalar nenhum aplicativo para me ajudar a fazer isso, pois isso é algo que planejo raramente fazer.

Qualquer sugestão ou ajuda que me guie na direção certa seria muito apreciada.

earthmeLon
fonte
Para qualquer um que está procurando mais fácil se aproxima para emuladores, consulte aqui: stackoverflow.com/questions/3391160/...
Mygod

Respostas:

21

Sim, você realmente pode fazer isso. É meio esquisito quando você inspeciona a área de transferência, mas funciona muito bem.

Primeiro, você pode inspecionar o conteúdo atual da área de transferência a service call clipboard 1partir de um shell adb (ou, sem casca antes adb shell service call clipboard 1). Pode começar inicialmente em branco após uma reinicialização, por exemplo:

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

Você pode colocar texto na área de transferência usando service call clipboard 2, o que basicamente leva três parâmetros - duas polegadas e a string que você deseja colocar na área de transferência:

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

Para ser sincero, não sei ao certo quais são os dois primeiros parâmetros. Uma resposta no Stack Overflow sugeriu que o primeiro int é "número de itens no pacote" (um neste caso) e que o segundo é o comprimento da string. No entanto, usei 0 para o segundo parâmetro e ele funciona bem, e não consigo encontrar nenhuma documentação que corresponda a essa função específica ...

De qualquer forma, é basicamente criar um objeto Parcel com 3 campos e passá-lo para a área de transferência. A área de transferência descompacta o pacote e define o valor da sequência passada como o conteúdo da área de transferência. Você pode ver isso quando recuperar o valor posteriormente:

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

Da mesma forma, se você pressionar longamente um campo de entrada de texto e pressionar "Colar" depois de fazer isso, receberá o texto que foi definido através da call service clipboard 2linha acima (e parecerá completamente normal).

(Os exemplos acima são do meu HTC EVO, executando o CyanogenMod 7)

eldarerathis
fonte
11
Finalmente posso colar minha chave WPA e conectar ao meu roteador: D. Obrigado.
earthmeLon
3
@earthmeLon se você estava apenas tentando encontrar uma maneira fácil de copiar sua chave WPA, na próxima vez você achar mais fácil fazer algo como enviá-la por e-mail para você e copiar / colar do e-mail ou copiar um arquivo de texto que a contenha dispositivo via USB, abra e copie a partir daí. Existem outras opções, como o Wifi Keyboard, que permitem digitar (ou colar) em um PC e fazer com que ele apareça no telefone.
precisa
4
Minha chave WPA é sensível. Ele não deve ser transmitido por nenhuma rede não local NUNCA. Obrigado pelas sugestões @GAThrawn. Eu encontrarei mais uso para essa funcionalidade eventualmente: D
earthmeL:
6
Eu recebo '........U.n.k.n.' 'o.w.n. .p.a.c.k.' 'a.g.e. ..... ')ao fazercall service clipboard 2
cprcrack
3
No caso de você precisa copiar sua senha ou qualquer texto em um campo de texto no Android você também pode "abd shell texto de entrada 'String'" - Eu desisti na área de transferência ...
Philippe
14

Eu usei essa metodologia e funcionou bem no 4.x, mas falhou para mim no pirulito. Enquanto procurava por uma solução alternativa, encontrei o seguinte: /programming/3391160/paste-text-on-android-emulator

não é exatamente como você queria, mas para mim, na maioria das vezes, quero copiar texto para a área de transferência é porque quero colá-lo no campo de senha.

como um bônus adicional, aqui está o meu script ( editado em 24-04-2015 para permitir espaços no 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
fonte
O motivo pelo qual você precisa escapar duplamente da string é que existem duas conchas: sua shell e a shell adb . No entanto, suspeito que isso falhará para outros caracteres que tenham um significado especial no shell, como o e comercial .
Dan Dascalescu
Na verdade, seria tarefa do shell adb fazer isso de forma adequada, mas aparentemente não o faz completamente. Na minha versão (1.0.31), o escape de espaço usado acima não é necessário, mas todos os tipos de caracteres especiais precisariam ser escapados (mas é impossível fazer isso de maneira confiável).
Matthijs Kooijman
Uma maneira melhor de lidar com caracteres especiais seria canalizar através de stdin, algo como: echo "$TEXT" | adb shell xargs -0 input textQual deve lidar com qualquer texto, exceto caracteres \ 0 (NUL). Infelizmente, versões mais antigas do adb não encaminham stdin para um comando especificado na linha de comando do adb. Isso foi corrigido nas versões adb mais recentes, mas ele precisa do Android N para funcionar .
Matthijs Kooijman
Quanto ao espaço que está escapando, isso é aparentemente necessário para o inputcomando no dispositivo Android, não para o shell usado pelo adb shell. Além disso, é necessário apenas para a versão 22 do SDK e abaixo (pirulito e abaixo, acredito) de acordo com esta resposta .
Matthijs Kooijman
4

Aqui está uma versão aprimorada do script por galets acima. Assim como o script, ele não grava na área de transferência, mas envia entrada para o campo de entrada atualmente focado, que geralmente é o que você deseja.

Este script foi aprimorado para escapar de caracteres especiais para evitar confundir o shell do Android com eles. Isso deve permitir que qualquer sequência seja enviada inalterada. Para impedir que o readcomando interprete uma barra invertida (à direita), adicionei -r lá.

Isso foi testado usando a seguinte lista de caracteres especiais:

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

Aqui está o script:

#!/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
fonte
3

Eu tentei e pesquisei um pouco no Google e parece que a abordagem de chamada-serviço-área de transferência parou de funcionar em androids mais novos, mas falhou para mim em uma versão 4.4.4 do Android. Ou seja, você precisará de um aplicativo para obter acesso à área de transferência (leitura e gravação) no adb-shell. Eu uso o clipper do majido no github . O apk também está hospedado, portanto, não é necessário compilá-lo. Quando instalado, você pode se comunicar usando comandos de transmissão (o aplicativo informará os comandos exatos). O aplicativo não requer raiz.

Sascha N.
fonte
Como não sabemos qual é o seu objetivo: você pode editar sua postagem e incluir o que esse aplicativo faz e como usá-lo? As pessoas já começam a sinalizar sua postagem como "não uma resposta", pois obviamente não entendem o que você deseja fazer. Desde já, obrigado!
Izzy
clipper funcionou melhor para mim do que usar 'adb shell input text'. Ainda melhor que o script Python AdbPaste github.com/gcb/AdbPaste para agrupar 'adb shell input text'. Aprimorei o clipper para suportar um parâmetro de arquivo, para que agora eu possa enviar várias páginas para a área de transferência em apenas um ou dois segundos. Código reforçada aqui: github.com/RoundSparrow/clipper
RoundSparrow hilltx
0

Outro script usado adb shell inputpara enviar caracteres pode ser encontrado aqui: https://github.com/gcb/AdbPaste

Este é um script Python que pode ser clonado no github ou também baixado e executado diretamente:

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