プログラミング

Androidで写真を撮影したらWindowsのクリップボードにURLをコピーする

Androidで写真を撮影したらWindowsのクリップボードにURLをコピーするプログラムについて紹介します。

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_5d270c96-26ba-4399-b357-04fb86aaf306.png

Android開発はしたことがない、なぜなら開発環境の構築で挫折しているから。どうもyuisです。僕みたいなandroid嫌いなわけではないけどなんか無理って人には、IFTTTがおすすめなんです。僕はIFTTTは日本ではほとんど名前聞かないくらいのころから存じておりましたが、あれはプログラミングができない人が使うものだ、俺らには関係ない。とずっと思っておりました、が…実はIFTTTは結構プログラマブルなんですよね。というのは、他のIFTTT記事や今回の記事を読んでいただければわかります。

今回はandroidで動画や…動画はできなかった、画像、写真を撮影したら、いろいろ内部で処理して、最終的にWindows 10のクリップボードに公開URLをコピーする、ということをします。

全体の流れ

ひとつひとつやってることは難しいことではないのですが、使う技術は相変わらず多いので、場合によっては時間がかかるかもしれませんが、これができると他のandroidのデータのやりとりにも応用できるのでぜひがんばってみてください。

  1. androidで写真を撮ったらIFTTTにアップロードされてURLが発行され、それがサーバーに送られる
  2. ubuntuのsinatraサーバーでそれを受け取ってパースしてファイルにテキストを保存
  3. テキストファイルからWSLからURLを取得する。そのURLを使い続けるのはインセキュアなので、wgetしてローカルに入れてから、いろいろ処理してリモートのサーバーにアップロードしてそのURLをクリップボードにコピー

事前準備

  • ポートフォワーディングができるWifiルーターにしましょう。

ポート転送をすることで、ローカルで動かしているサーバーをグローバルIPの公開URLからリクエストするため、そういうルーターでない方は買いましょう。幸運にも、どのルーターを買えばいいのかは明白です。

光回線工事後、4台のルーターを実際に買って検証した結果導き出された最高のwifiルーターとは

  • WSL

WSL(Windows Subsystem for Linux)を初期から使っている僕がLinuxやプログラミングの初心者向けにWSLのメリットを解説してみる
WSL bash on ubuntu on windows インストール手順

  • Ruby環境を作りましょう

Rubyでsinatraを動かします。3分でできるのでささっと環境を作りましょう。

sudo apt update ; sudo apt install build-essential patch zlib1g-dev liblzma-dev ruby{,-dev} -y ; sudo gem install bundler

mkdir -p /mnt/c/pg/ruby_dev && cd $_

sudo bundle init
vim Gemfile
sudo bundle install

vim Gemfile

# add
gem "pry"
gem "sinatra"

手順

  • wifiルーターでポートフォワーディングの設定をします

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_056219d2-d4f2-4e9d-89a5-0c6ec5a927bf.png

  • IFTTTでアプレットを作ります

Make an Applet – IFTTT

this … android photo
that … webhooks

title(例) … If Any new photo, then post request to server
URL(例) … http://220.247.111.111:8005/android-photo
method … post
type … json
body … { "TemporaryPublicPhotoURL": "{{TemporaryPublicPhotoURL}}", "TakenDate": "{{TakenDate}}" }

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_ff07fd64-5594-4260-8146-180bb4e4ab55.png

  • Windowsのフォルダをマウントしてファイルを同期できるようにしておきます
sudo mount -t  cifs //192.168.0.167/_sync_ ~/share -o user=ifgm2,pass=hoge,dir_mode=0777,file_mode=0777

Ubuntu 18.04でWindows 10の共有フォルダをマウントする方法
windows 10のシェア(共有)フォルダをubuntu16.04でマウント(同期)する

シェアディレクトリのandroid-photo-url.txtにデータをストアしておき、それをWSLで定期的に読み取って処理する、ということをあとで実装します。

  • sinatraを動かします

require "sinatra"
require "open3"
require 'json'
require 'pry'

Encoding.default_external = 'UTF-8'


post "/android-photo" do

    binding.pry

    # puts "ok"
    puts @body = request.body.read

        json = JSON.parse( @body )
        puts text = json["TemporaryPublicPhotoURL"]

        stdout, stderr, statusCode = Open3.capture3( %( bash -ic "printf '#{ text }' > /home/yuis/share/android-photo-url.txt || echo '' " ) )

    puts stdout, stderr, statusCode

end



sudo bundle exec ruby dev.rb -o 0.0.0.0
  • WSL側で使用する関数を定義してください

今回はexpectosharefileを使っています。
expectはexpectを使いやすくしたもので、sharefileはリモートサーバーにローカルファイルを公開URLとして公開したのちクリップボードにコピーするユーティリティです。

上記2つの関数のコードは以下それぞれの記事にて参照してください。

パスワード省略できないサーバーにexpect経由で自動SSHする
Bash リモートサーバーにファイルをコピーして共有のためのURLを取得する

はじめてのBash。関数やエイリアスを読み込むまで [初心者向け]

上記2つ以外の関数など



tmpdird ()
{
    : tmpdir default;
    dirname=$(plaindate) && cd "${TMPDIR}" && mkdir $dirname && cd $dirname
}


plaindate ()
{
    date '+%Y%m%d%H%M%S'
}



random ()
{
    ARG1=${1:-32};
    cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $ARG1 | head -n 1
}


  • WSL側で定期的にコマンドテキストの入ったファイルを監視するスクリプトを実行します

conemuなどで以下のスクリプトを実行して放置。

while true; do

    echo -ne "$(isodate)\tNothing updated.\033[0K\r"

    [[ -s "$SHAREDDIR/android-photo-url.txt" ]] && {
        tmpdird
        wget "$( cat "$SHAREDDIR/android-photo-url.txt" )"
        # sed -Ee 's/.*\.(\w+)\?.*/\1/g' # extract extension, in need
        filename="android_photo_$(random).jpg"
        mv "$( command ls -1 | head -1 )" "${filename}"
        pwd > ~/pwd.txt
        eval "$(echo "expecto 'bash -ic \"cd \\"$(cat ~/pwd.txt)\\" ; sharefile ${filename}\"' $XSERV_PASSWORD")"
        printf "Copied remote photo url to clipboard." ;
        > "$SHAREDDIR/android-photo-url.txt"
    }

    sleep 2s
done

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_7ad36b6d-d722-46e0-9227-6ad333b33e6e.png

今回はbashのコードのほうが複雑になりました。sharefileをパスワード入力無しでやろうとした結果です。

説明が必要そうですので、軽く説明します。

tmpdird

ファイルが一つしかない状態が望ましいので、テンポラリーディレクトリを作ってそこへ移動します。

wget "$( cat "$SHAREDDIR/android-photo-url.txt" )"

IFTTTのURLをローカルに保存します

filename="android_photo_$(random).jpg"

ファイル名を作成

mv "$( command ls -1 | head -1 )" "${filename}"

IFTTTから保存したファイルの名前を変更

pwd > ~/pwd.txt

bash -icしてしまうと、サブプロセスなのでカレントディレクトリが変わってしまいます。なので、まずカレントディレクトリの情報を↑でファイルに保存し、次のステップでそれをbash -icのなかでコマンドしてcdします。

eval "$(echo "expecto 'bash -ic \"cd \\"$(cat ~/pwd.txt)\\" ; sharefile ${filename}\"' $XSERV_PASSWORD")"

expectoの第一引数は展開なしの生のコマンドである必要があります。なので単純に、全てechoで展開してからevalしてやります。少し複雑。

> "$SHAREDDIR/android-photo-url.txt"

ファイルを空にしてます。

  • 実際に動くかテストします

なんか問題があればコメントしてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です