Копируем текст из буфера обмена на Android девайсы через ADB


    Привет! Вы сталкивались с желанием скопировать какой-нибудь текст на лежащий рядом девайс? Мне хотелось бы, чтобы это было так же просто, как и copy-paste на эмулятор — набирать руками надоедает и не всегда удобно.


    А что насчет хоткея: нажимаете его, и текст из буфера обмена PC начинает сам набираться на экране вашего телефона/планшета — звучит неплохо, верно?


    В этой статье мы поговорим про использование adb в качестве инструмента копирования текста и о том, как это можно сделать удобным.


    Если вы опытный пользователь adb, и у вас есть собственный скрипт такого рода — советую перейти к самой реализации и поделиться своими мыслями по этому поводу в комментариях.


    Что и зачем


    Мы сделаем маленький скрипт, который позволит быстро набрать содержимое буфера обмена на реальном девайсе:



    Это пригодится, если:


    • Проверяете работу со ссылками или вводите новый ip для настройки прокси на девайсе в очередной раз:

    http://example.com:8080/foo
    192.168.1.100

    • Проверяете ввод спец символов или вводите хитрые тестовые данные:

    v3rY$ecUrEP@s$w0rD

    • Просто пришлось вводить длинную строчку:

    Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

    • Или тестовый ключ:

    BUexKeGHiERJ4YYbd2_Tk8XlDMVEurbKjWOWvrY

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


    В конце-концов чаще всего это были тестовые данные или настройки api, и скрипт хоть и не спасал 5 минут, но делал работу куда приятнее.


    А как?


    Это можно сделать при помощи ADB (Android Debug Bridge). Наверное, все разработчики и большинство QA знакомы с ним как минимум благодаря возможности просмотра логов внутри Android Studio или напрямую, через adb logcat. Если вы до этого не пользовались adb, пример установки на macOS можно посмотреть здесь.


    Нас интересует команда adb shell input, позволяющая осуществлять ввод, например tap или swipe.


    Она же позволяет передать текст — он начнет печататься в поле ввода, которое сейчас в фокусе:


    adb shell input text <text>

    Если вы вводите пробелы, их нужно заменить на %s, а спецсимволы заэскейпить. Иначе ничего не получится.


    Стоит учесть, что adb работает только с латинским алфавитом, цифрами и спецсимволами из ASCII таблички, и ввод несколько ограничен:


    1. Не работает с символами типа ±§
    2. Не работает с переносом строки (Но можно например отдельно вызвать перенос строки другой adb командой adb shell input keyevent 66 (enter) или как описано здесь)
    3. Не работает с кириллицей

    Есть интересный workaround для ввода подобных символов, возможно, к нему можно будет прикрутить буфер обмена и тогда уже печатать любой текст. Правда на девайс нужно будет предварительно поставить .apk с клавиатурой.


    Важно: В описанном выше и далее виде команды adb подразумевают, что подключен один девайс. Если же их несколько, можно сделать следующее:


    1) Вызвать команду на конкретный девайс. Опция -s
    Узнать номер девайса можно командой adb devices. Затем используем номер при вызове команды:


    $ adb devices
    List of devices attached
    023db62er9dd7d2b    device
    $ adb -s 023db62er9dd7d2b shell input text qwe

    2) Вызвать команду на единственный девайс, подключенный по usb — опция -d:


    adb -d shell input text qwe

    3) Вызвать команду на единственный активный эмулятор — опция -e:


    adb -e shell input text qwe

    Более подробно можно почитать здесь.


    Если вы работаете с несколькими девайсами и эти кейсы про вас, то поправьте adb команду соответствующим образом.


    Реализация


    Подробно рассмотрим решение для macOS, но для остальных систем тоже есть способ:


    • GNU/Linux
    • MacOS
    • Windows

    Решение для Linux

    В свое время ребята из KODE (Дима Суздалев и Дима Гайдук) сделали отличное решение для Linux и поделились им со мной.


    Оно работает через буфер X11 (Если у вас Wayland, читайте ниже) — вы выделяете текст для ставки, а потом нажимаете хоткей, который вызывает скрипт.


    Добавить такой хоткей несложно, нужно:


    1) Поставить xclip


    2) Добавить файл со скриптом


    #!/bin/bash
    adb shell input text `xclip -o`

    3) Прописать путь к скрипту в настройках Shortcuts для клавиатуры


    Ребятам спасибо и большой респект.


    Важно: решение выше работает для X11 (Xorg). Для Wayland это решение не актуально. Я так и не смог найти способ получать содержимое из буфера в Wayland, судя по моим поискам такой возможности пока нет. Поправьте, если не прав.


    Если вы не в курсе какая именно среда у вас — посмотрите сюда. Скорее всего, у вас X11 и все будет работать.


    Решение для macOS

    Для macOS linux решение не подошло, поэтому я попытался сделать похожий скрипт, который бы упрощал вызов adb shell input text <text>.


    Сразу скажу — работа с sed для меня не очевидна. Я попытался собрать в одну команду и немного дополнить разные регулярки замен, которые бы помогали правильно отэскейпить спецсимволы.
    Если придумаете как улучшить этот скрипт, будет очень круто!


    Выглядит он так:


    source ~/.bash_profile
    adb shell input text $(pbpaste | sed -e 's/[_<>|&$;()\"]/\\&/g' -e 's/ /\%s/g' -e 's/!+/!/g')

    (source ~/.bash_profile добавляется если в обычной консоли adb работает, но через Automator (об этом позже) adb не распознается, для этого сначала нужно подтянуть путь до adb — например, прописанный в ~/.bash_profile.)



    Работает как обычный adb shell input text <text>, но


    1. Источником текста является pbpaste — т.е буфер обмена macOS.
    2. sed обрабатывает текст из буфера обмена.
    3. Символы _<>&$;()\" эскейпятся: — & -> \&
    4. Пробелы заменяются на спецсимвол: ` ->%s`
    5. С восклицательном знаком все сложно — если кто мне объяснит подобная замена ! на ! помогает команде не свалиться — будет круто.

    Решение для Windows

    К сожалению (или нет) на Windows я не пробовал сделать подобное. Самый очевидный вариант, который мне приходит на ум — адаптировать решение и поставить Cygwin. Это позволит иметь удобный linux терминал под рукой, что наверняка пригодится.
    Вам нужен будет пакет sed и зависимости к нему и пакет cygutils-extra (предоставляет команду получения содержимого буфера обмена — getclip на замену pbpaste)


    Результат будет очень похож на решение для macOS:


    adb shell input text $(getclip | sed -e 's/[_<>|&$;()\"]/\\&/g' -e 's/ /\%s/g' -e 's/!+/!/g')

    В Windows 10 также есть возможность получить Linux терминал из коробки. Такой вариант не пробовал, но он должен быть похож на решение с Cygwin.



    Скрипт в действии


    Упрощаем работу


    Можно каждый раз копировать скрипт в консоль или набивать руками adb shell input text <something>, но это не слишком удобно. Проще сделать alias или назначить хоткей.


    Про alias для консоли

    Здесь сложность в том, что в самом alias вам нужно будет еще заэскейпить все $ и ", чтобы он заработал. Я этим пока не занимался, поскольку хоткей мне удобнее. Правда до этого использовал такой — alias adp='adb shell input text' который помогал набрать одно слово типа adp example. Если кто-то сделает себе alias со скриптом, напишите — прикрепим сюда.


    Про хоткей, который будет запускать скрипт

    Если говорить про Linux решение — все зависит от дистрибутива, но это тоже не сложно.


    Решение для Windows на Cygwin — вот простой способ.


    Изначально статья была для внутреннего использования, поэтому способ под macOS описан более детально, его можно посмотреть ниже:


    Способ для macOS:

    Здесь много вариантов как это сделать, но по умолчанию установлен Automator — можно быстро сделать хоткей при помощи него.


    Для начала запускаем Automator, выбираем тип документа Service:



    Затем настраиваем service:


    • для service receives ставим no input
    • внутри вкладки Actions выбираем действие Run shell script


    Теперь на новый service можно назначить хоткей:



    Все, теперь копирование на девайс должно работать по хоткею.


    Правда service по хоткею будет работать только в приложениях, где в меню приложения есть вкладка Services:



    В приложении Zeplin для macOS такой вкладки нет, поэтому там это не работает. Возможно, другие приложения для использования скриптов могут обойти это ограничение, мне пока хватало способа через Automator.


    Стоит также учесть, что хоткей может перехватить тот же Google Chrome или другое приложение и выполнить свое действие вместо скрипта.


    Вот и все


    Надеюсь, статья будет полезной и поможет вам упростить решение подобных задач в своей работе.

    • +17
    • 3,1k
    • 6
    Redmadrobot 263,64
    №1 в разработке мобильных решений для бизнеса
    Поделиться публикацией
    Комментарии 6
    • +2
      Под Linux есть KDE Connect, который работает не только со смартфонами.
      • 0
        Выглядит интересно, не знал! ADB поддерживает ограниченный набор символов, здесь же эта проблема должна решиться.
        Правда нужно будет установить отдельное приложение и, как я понял, поставить хотя бы часть зависимостей от KDE. Если нет необходимости подключать разные телефоны и используется GNU/Linux, то это может быть неплохим решением.
        • 0

          Для Gnome есть аналог KDE Connect, но он у меня не заработал (поэтому даже название не запомнил). А вот KDE Connect работает отлично. Причем, позволяет не только текст копировать, но еще и перенаправляет уведомления, позволяет пересылать файлы в обе стороны. Очень удобная штука.

          • +1
            Для Gnome есть аналог KDE Connect, но он у меня не заработал (поэтому даже название не запомнил).
            GSConnect, его ещё не допилили, собирались доделать к релизу Ubuntu 18.10.
        • 0

          Только там, насколько я помню, буфер будет синхронизироваться постоянно — скопировал пароль, а он на все устройства улетел. :) Ну и там полно других компонентов, не только синхронизация буфера — удалённый доступ к файлам устройства или удалённая клавиатура/тачпад для компьютера, например. Вроде, можно было даже лазить с телефона сразу на планшет за файлами.

          • 0
            Есть такое дело. Есть и другие решения для синхронизации буфера, они похожи в том, что нужно поставить приложение на оба устройства и затем связать их.
            Когда используется какой-то основной, желательно личный девайс — это не проблема, да и дополнительные плюшки наверное пригодятся.
            Когда же множество устройств используется разными людьми (QA + dev отделы), это может быть не удобным. С adb все проще: достаточно подключить телефон и нажать кнопку.
            Тут кому что удобней :)

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое