logo
Published on

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

Authors

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

Android Photo

Android開発に関する経験がない方にも分かりやすく説明します。開発環境の構築で挫折したことがある方も、このプログラムを利用すれば簡単に写真のURLを取得できます。

Android開発は難しく思えるかもしれませんが、IFTTT(If This Then That)を使えば、プログラムの知識がない人でも簡単に自動化できます。IFTTTは日本ではあまり知られていないかもしれませんが、実はプログラミングの要素を含んでおり、多くの用途に適用できます。

今回のプログラムでは、Androidで写真を撮影したら、その写真を内部で処理し、最終的にWindows 10のクリップボードに公開URLをコピーする方法を紹介します。

全体の流れ

このプログラムの全体の流れを説明します。個別のステップは難しくありませんが、多くの技術を使用するため、時間がかかるかもしれません。しかし、一度理解すれば、他のAndroidアプリ開発にも応用できるでしょう。

  1. Androidで写真を撮影すると、IFTTTがその写真をアップロードし、URLを生成します。このURLはサーバーに送信されます。
  2. Ubuntu上のSinatraサーバーがこの情報を受け取り、データを解析してテキストファイルに保存します。
  3. テキストファイルをWSL(Windows Subsystem for Linux)から読み取り、URLを取得します。セキュリティ上の理由から、URLをそのまま使用せず、ローカルにダウンロードして処理し、リモートサーバーに再アップロードしてからクリップボードにコピーします。

事前準備

事前に以下の準備をしておく必要があります。

  • ポートフォワーディングができるWiFiルーターを使用します。ポートフォワーディングを設定することで、ローカルサーバーをグローバルIPの公開URLからアクセスできるようになります。

ルーターの選定に関する情報はこちら

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

Gemfileに以下の行を追加します。

gem "pry"
gem "sinatra"

手順

以下はプログラムを実行する手順です。

  1. WiFiルーターでポートフォワーディングを設定します。ポートフォワーディングを有効にすることで、外部からローカルサーバーにアクセスできるようになります。

WiFiルーターのポートフォワーディング設定

  1. IFTTTでアプレットを作成します。IFTTTを使用してAndroidの写真を検知し、サーバーにデータを送信します。

IFTTTのアプレット作成はこちら

  1. Windowsのフォルダをマウントしてファイルを同期できるようにします。これにより、ローカルとリモートのデータを同期させることができます。

以下のコマンドを実行します。

sudo mount -t cifs //192.168.0.167/_sync_ ~/share -o user=ifgm2,pass=hoge,dir_mode=0777,file_mode=0777
  1. Sinatraアプリケーションを起動します。SinatraはRuby製のWebアプリケーションフレームワークで、IFTTTからのデータを受け取ります。

以下はSinatraのコード例です。

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

Encoding.default_external = 'UTF-8'

post "/android-photo" do
    binding.pry
    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
  1. WSL側で使用する関数を定義します。このプログラムではexpectosharefileという2つの関数を使用します。

expectoはSSH接続を自動化するためのユーティリティで、sharefileはローカルファイルをリモートサーバーにアップロードし、そのURLをクリップボードにコピーするユーティリティです。

これらの関数の詳細なコードは以下の記事で確認できます。

また、他の関数も以下のように定義されています。

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
}
  1. WSL側で、コマンドテキストが入ったファイルを定期的に監視するスクリプトを実行します。このスクリプトは、ファイルが更新された際にその内容を処理し、クリップボードにコピーします。

以下はスクリプトの例です。

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" )"
        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

このスクリプトは、ファイルの監視、URLのダウンロード、ファイルのリネーム、クリップボードへのコピーなどを行います。

これらの手順を実行することで、Androidで写真を撮影し、その写真のURLをWindowsのクリップボードに簡単にコピーするプログラムを構築できます。問題がある場合は、コメントで質問してください。