Можно ли писать в буфер обмена устройства с помощью ADB?

Мне интересно узнать, как записывать (и, если возможно, читать) буфер обмена Android-устройства с root-правами.

Я надеюсь сделать это с помощью ADB через USB, и я не заинтересован в установке каких-либо приложений, которые помогут мне в этом, так как это то, что я планирую делать редко.

Любые предложения или помощь, направляющие меня в правильном направлении, будут очень признательны.

Для тех, кто ищет более простые подходы к эмуляторам, смотрите здесь: stackoverflow.com/questions/3391160/…

Ответы (5)

Да, вы действительно можете это сделать. Когда вы проверяете буфер обмена, это выглядит неуклюже, но работает просто отлично.

Во-первых, вы можете проверить текущее содержимое буфера обмена с service call clipboard 1помощью оболочки adb (или, без предварительной оболочки, adb shell service call clipboard 1). После перезагрузки он может начинаться пустым, например:

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

Вы можете поместить текст в буфер обмена, используя service call clipboard 2, который в основном принимает 3 параметра — два целых числа и строку, которую вы хотите поместить в буфер обмена:

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

Честно говоря, я не уверен, что такое первые два параметра. Один ответ на Stack Overflow предполагает, что первое int — это «количество предметов в посылке» (в данном случае один), а второе — длина строки. Тем не менее, я использовал 0 для второго параметра, и он работает нормально, и я не могу найти никакой документации, которая соответствует этой конкретной функции... так что примите это за то, что оно того стоит.

В любом случае, это в основном создание объекта Parcel с 3 полями, а затем передача его в буфер обмена. Затем буфер обмена распаковывает Parcel и устанавливает переданное строковое значение в качестве содержимого буфера обмена. Вы можете увидеть это, когда перейдете к получению значения после этого:

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

Точно так же, если вы долго нажмете на поле ввода текста и после этого нажмете «Вставить», вы получите текст, который был установлен в call service clipboard 2строке выше (и он будет выглядеть совершенно нормально).

(Вышеприведенные примеры взяты из моего HTC EVO с CyanogenMod 7)

Наконец-то я могу вставить свой ключ WPA и подключиться к своему маршрутизатору :D. Спасибо.
@earthmeLon, если вы просто пытались найти простой способ скопировать свой ключ WPA, то в следующий раз вам может быть проще сделать что-то, например, отправить его себе по электронной почте и скопировать/вставить из электронной почты или скопировать текстовый файл, содержащий его, на свой устройство через USB, затем откройте и скопируйте оттуда. Существуют и другие варианты, такие как клавиатура Wi -Fi , которые позволяют вводить (или вставлять) текст с ПК и отображать его на телефоне.
Мой ключ WPA чувствителен. Он не должен транслироваться по какой-либо нелокальной сети НИКОГДА. Спасибо за предложения @GAThrawn. Со временем я найду больше применения этой функции :D
копирование файла через usb является локальным
я получаю '........U.n.k.n.' 'o.w.n. .p.a.c.k.' 'a.g.e. ..... ')при изготовленииcall service clipboard 2
жаль это больше не работает
Из этого связанного сообщения кажется, что, возможно, эти дополнительные параметры должны быть именем пакета и чем-то еще?
Вы случайно не знаете, что эквивалентно леденцу на палочке? Эта команда работала в kitkat, но не в леденце.
Если вам нужно скопировать свой пароль или любой текст в текстовое поле на Android, вы также можете «abd shell input text 'String'» - я отказался от буфера обмена...

Я использовал эту методологию, и она отлично работала в 4.x, но у меня не получилось в леденце. При поиске альтернативного решения я нашел это: https://stackoverflow.com/questions/3391160/paste-text-on-android-emulator

это не совсем так, как вы хотели, но для себя я чаще всего хочу скопировать текст в буфер обмена, потому что я хочу вставить его в поле пароля.

в качестве дополнительного бонуса, вот мой сценарий ( отредактированный 24 апреля 2015 г., чтобы разрешить пробелы в тексте ):

#!/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"
Причина, по которой вам нужно дважды экранировать строку, заключается в том, что есть две оболочки: ваша оболочка и оболочка adb . Однако я подозреваю, что это не сработает для других символов, имеющих особое значение в оболочке, таких как амперсанд .
На самом деле задачей оболочки adb было бы правильно выполнить это экранирование, но, по-видимому, это не полностью. В моей версии (1.0.31) экранирование пробелами, использованное выше, не требуется, но все виды специальных символов необходимо экранировать (но это невозможно сделать надежно).
Лучшим способом обработки специальных символов будет передача через стандартный ввод, что-то вроде: echo "$TEXT" | adb shell xargs -0 input textКоторый должен обрабатывать любой текст, кроме символов \0 (NUL). К сожалению, более старые версии adb не пересылают стандартный ввод команде, указанной в командной строке adb. Это исправлено в более новых версиях adb, но для работы требуется Android N.
Что касается экранирования пробела, то это, по-видимому, необходимо для inputкоманды на Android-устройстве, а не для оболочки, используемой adb shell. Кроме того, это необходимо только для SDK версии 22 и ниже (я полагаю, Lollipop и ниже) в соответствии с этим ответом .

Вот улучшенная версия скрипта от galets выше. Как и в случае с этим сценарием, он не записывает в буфер обмена, а отправляет ввод в поле ввода, которое в данный момент находится в фокусе, что в любом случае часто требуется.

Этот скрипт улучшен для экранирования специальных символов, чтобы не путать с ними оболочку Android. Это должно разрешить отправку любой строки без изменений. Чтобы readкоманда не интерпретировала (завершающую) обратную косую черту, я добавил туда -r.

Это было протестировано с использованием следующего списка специальных символов:

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

Вот сценарий:

#!/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"

Я пробовал и немного гуглил, и кажется, что подход call-service-clipboard перестал работать в более новых андроидах, у меня не получилось на версии Android 4.4.4. То есть вам понадобится приложение для доступа к буферу обмена (чтение и запись) из adb-shell. Я использую clipper от majido на github . APK-файл также размещен на хостинге, поэтому его не нужно компилировать самостоятельно. После установки вы можете общаться с ним с помощью широковещательных команд (приложение сообщит вам точные команды). Приложение не требует рута.

Поскольку мы не знаем, какова ваша цель: не могли бы вы отредактировать свой пост и указать, что делает это приложение и как его предполагается использовать? Люди уже начинают помечать ваш пост как «не ответ», так как они явно не понимают, о чем вы хотите сказать. Заранее спасибо!
clipper работал лучше для меня, чем использование «ввода текста adb shell». Даже лучше, чем скрипт Python AdbPaste github.com/gcb/AdbPaste для переноса «вводного текста оболочки adb». Я расширил clipper для поддержки параметра файла, поэтому теперь я могу отправлять несколько страниц в буфер обмена всего за секунду или две. Расширенный код здесь: github.com/RoundSparrow/clipper

Другой скрипт, который используется adb shell inputдля отправки символов, можно найти здесь: https://github.com/gcb/AdbPaste .

Это скрипт Python, который можно клонировать с github, а также напрямую загрузить и запустить:

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