- Published on
Androidで写真を撮影したらWindowsのクリップボードにURLをコピーする
- Authors
- Name
- Shou Arisaka / 有坂翔
今回は、Androidで写真を撮影した際に、その写真のURLをWindowsのクリップボードにコピーするプログラムについて紹介します。
Android開発に関する経験がない方にも分かりやすく説明します。開発環境の構築で挫折したことがある方も、このプログラムを利用すれば簡単に写真のURLを取得できます。
Android開発は難しく思えるかもしれませんが、IFTTT(If This Then That)を使えば、プログラムの知識がない人でも簡単に自動化できます。IFTTTは日本ではあまり知られていないかもしれませんが、実はプログラミングの要素を含んでおり、多くの用途に適用できます。
今回のプログラムでは、Androidで写真を撮影したら、その写真を内部で処理し、最終的にWindows 10のクリップボードに公開URLをコピーする方法を紹介します。
全体の流れ
このプログラムの全体の流れを説明します。個別のステップは難しくありませんが、多くの技術を使用するため、時間がかかるかもしれません。しかし、一度理解すれば、他のAndroidアプリ開発にも応用できるでしょう。
- Androidで写真を撮影すると、IFTTTがその写真をアップロードし、URLを生成します。このURLはサーバーに送信されます。
- Ubuntu上のSinatraサーバーがこの情報を受け取り、データを解析してテキストファイルに保存します。
- テキストファイルをWSL(Windows Subsystem for Linux)から読み取り、URLを取得します。セキュリティ上の理由から、URLをそのまま使用せず、ローカルにダウンロードして処理し、リモートサーバーに再アップロードしてからクリップボードにコピーします。
事前準備
事前に以下の準備をしておく必要があります。
- ポートフォワーディングができるWiFiルーターを使用します。ポートフォワーディングを設定することで、ローカルサーバーをグローバルIPの公開URLからアクセスできるようになります。
WSL(Windows Subsystem for Linux)をインストールしておきます。WSLを使用することでLinuxコマンドをWindowsで利用できます。
Ruby環境をセットアップします。Sinatraフレームワークを使用するためにRubyが必要です。以下はRuby環境をセットアップする手順です。
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"
手順
以下はプログラムを実行する手順です。
- WiFiルーターでポートフォワーディングを設定します。ポートフォワーディングを有効にすることで、外部からローカルサーバーにアクセスできるようになります。
- IFTTTでアプレットを作成します。IFTTTを使用してAndroidの写真を検知し、サーバーにデータを送信します。
- Windowsのフォルダをマウントしてファイルを同期できるようにします。これにより、ローカルとリモートのデータを同期させることができます。
以下のコマンドを実行します。
sudo mount -t cifs //192.168.0.167/_sync_ ~/share -o user=ifgm2,pass=hoge,dir_mode=0777,file_mode=0777
- 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
- WSL側で使用する関数を定義します。このプログラムでは
expecto
とsharefile
という2つの関数を使用します。
expecto
はSSH接続を自動化するためのユーティリティで、sharefile
はローカルファイルをリモートサーバーにアップロードし、そのURLをクリップボードにコピーするユーティリティです。
これらの関数の詳細なコードは以下の記事で確認できます。
- パスワード省略できないサーバーにexpect経由で自動SSHする
- Bash リモートサーバーにファイルをコピーして共有のためのURLを取得する
- はじめてのBash。関数やエイリアスを読み込むまで [初心者向け]
また、他の関数も以下のように定義されています。
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側で、コマンドテキストが入ったファイルを定期的に監視するスクリプトを実行します。このスクリプトは、ファイルが更新された際にその内容を処理し、クリップボードにコピーします。
以下はスクリプトの例です。
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のクリップボードに簡単にコピーするプログラムを構築できます。問題がある場合は、コメントで質問してください。