経緯
大学の自由研究でキャンパス内を循環しているバスの位置情報やバス内の画像を解析して、Web上でバスの現在位置や混雑状況などを確認できるサービスを4人チームで開発することになった。
チーム全体の開発が一段落し、自分の担当した領域をまとめようと思い投稿しました。
自分の担当した内容に絞ってまとめているため分かりずらい点があるかもしれません。分かりずらい点や修正した方が良い点などがあれば報告していただけるとすごくありがたいです。
他の担当者の内容はslideshareに載せてある資料を参照してください。
大学循環バスシステムをチームで開発してみる。
ソースコードはGitHubに載せています。
1.序論
1.1 バスクライアントとは
このシステムで私はバスクライアントの開発を担当した。
バスクライアントの役割はバスの位置情報と混雑状況を計測するための
バス内の画像をAPIサーバに送信することである。
これはシステム全体の中でのバスクライアントの役割である。
1.2仕様
以下の3つの機能を持たせたAndroidアプリを開発し、そのアプリをインストールさせたAndroid端末をバス内に設置することでバスクライアントを実現する。
- Wi-FiとGPSから取得した位置情報データを10秒ごとにAPIサーバに送信する。
- バス内の画像をBase64にエンコードしてから10秒ごとにAPIサーバに送信する。
- 1.と2.の送信データはJSON形式で送信する。
JSONデータの中身 (左:位置情報、右:画像情報)である。
1.3使用した環境
- 統合開発環境:Android Studio
- 使用した言語:Java
- 使用したAndroid端末:VAIO Phone A VPA0511S
1.4 ファイルの説明
tamabus
├ AndroidManifest.xml
├ MainActivity.java
├ UploadTask.java
├ activity_main.xml
├ colors.xml
├ strings.xml
└ styles.xml
- AndroidManifest.xml:使用する権限を記載してあるファイル
- MainActivity.java:ここに記載されているプログラムが動作する。
- UploadTask.java:サーバにデータをPostする際の非同期通信処理のクラス
- activity_main.xml:アプリ画面のレイアウトが記載されているファイル
- colors.xml,strings.xml,styles.xml:それぞれアプリ内で使用されている色や文字列、書式などの情報が記載されているファイル。
2.本論
2.1 アプリ画面、機能の流れ
以下がアプリの画面である。常時カメラを起動し、AndroidのGUIコンポ―ネントであるTextureViewオブジェクトに映し続けている。
TextureViewオブジェクトの下には、青文字で緯度、赤文字で経度を表している。緯度、経度の下にはアプリを起動してからの経過時間を示している。
経過時間は10秒ごとに更新され、経過時間が更新されると位置情報と画像情報が送信されたことが分かるようになっている。
アプリを起動してからのフローは以下の通りである。
変数などの初期化処理が行われた後、位置情報権限とカメラ使用権限が許可されているかどうかを確認する。両権限が許可されていれば、「GPSから位置情報を取得」から「エンコードした画像をPost」までのフローを10秒おきにループする。
2.2 発生した課題
2.2.1 カメラを全自動で撮影できない。
開発当初、カメラでの自動撮影はAndroid StudioのIntentクラスの機能を使って、純正のカメラアプリを呼び出し、起動したカメラアプリで自動的に撮影できるものだと思っていた。しかし、純正のカメラアプリでは誰かがシャッターを押さなければ写真が撮影できず、自動的に撮影ができないことが分かった。どのようにしてバス内の画像を取得するかが開発当初の一番の課題であった。
2.2.2 Postされたエンコード済み画像データを受信側でデコードできない。
バスクライアント側で撮影した画像をBase64でエンコードし、文字列化した画像データをテストでlocalhostに送信する。受信側で画像データの文字列を受け取ることに成功したが文字列をデコードすることができなかった。
2.3 発生した課題の解決法
2.3.1 純正のカメラアプリを起動しない。
純正のカメラアプリを起動し、シャッターを押して撮影する方法以外に画像を取得する方法はないか、情報を探していたがなかなか見つからなかった。そこで英語で情報を探してみれば見つかるのでは、と考え英語で情報を探してみるとカメラに写っているものをGUIコンポーネントのTextureViewオブジェクトに取り込み、一定時間でTextureViewオブジェクトに移っている画像を取り込むという方法を見つけ、この方法で課題を解決することができた。
2.3.2 Postすると+記号が半角スペースに強制的に置換される。
エンコードされた文字列を送信する前にAndroid側でデコードすると正しくデコードできたことから、Postに原因があるのではないかと推測した。調べてみると、Postした文字列内の+記号が半角スペースに置換されてしまう事が分かった。
テストでlocalhostにデータを送信した。以下の赤線部が半角スペースに変換された箇所である。
サーバ側で受信した文字列に含まれる半角スペースを+記号に置換するプログラムを作成することで課題を解決した。
3.結論
3.1 localhostに送信してみた
XAMPPで受信した位置情報と画像情報のJSONデータを表示する環境をlocalhostに構築した。
正しくデータを送信できていることが分かる。
3.2 今後の予定
私の担当であるバスクライアントは完成したので送信された画像から混雑度を解析する画像解析を今後手伝う予定である。
メンバーで予定を調整して開発を再開して、運用までもっていきたい。