AndroidからDropboxのcore APIを使って,dropboxから写真をダウンロードせずにジオタグと撮影時刻を取得する方法です.
Dropboxの写真から高速にジオタグを取得する
拙作のAndroidアプリ
GPXフォトサーチ
への機能追加の関係で,
- Dropboxにアップしてある写真をダウンロードせずに,ジオタグ(GPS緯度経度)と撮影時刻を取得する
ということをやりましたので,その方法を説明します.
Android版Core APIの機能
用途的に,
sync API
より
core API
の方が適してそうですが,
Android版のcore APIをダウンロードしても,それらしき機能はありませんでした.
Core APIの本体
それで,Core APIの本体(HTTPインターフェイス)を調べたところ,/metadata にそれらしき機能がありました.
リクエストパラメータのinclude_media_infoをtrueにすると,
対象が画像ファイルの場合はレスポンスにphoto_infoが含まれるとのことです.
そしてphoto_infoには,
- lat_long : GPS緯度経度
- time_taken : 撮影時刻
が含まれます.これは使えそうです!
ということで,Android版Core APIのソース(DropboxAPI.java)を元にして,
このphoto_infoに対応した呼び出しメソッドとentityクラスを作ってみました.
(説明用なのでエラーチェックはかなり省いています.適宜入れてください)
import
org.json.simple.JSONArray;
import
org.json.simple.JSONObject;
import
com.dropbox.client2.DropboxAPI;
import
com.dropbox.client2.DropboxAPI.Entry;
import
com.dropbox.client2.RESTUtility;
import
com.dropbox.client2.RESTUtility.RequestMethod;
import
com.dropbox.client2.android.AndroidAuthSession;
import
com.dropbox.client2.exception.DropboxException;
import
com.dropbox.client2.exception.DropboxUnlinkedException;
import
com.dropbox.client2.session.AppKeyPair;
public
static
PhotoEntry metadataWithPhotoInfo(DropboxAPI<AndroidAuthSession> api,
String path, int
fileLimit, String hash,
boolean
list, String rev) throws
DropboxException {
AndroidAuthSession session = api.getSession();
String[] params = {
"file_limit"
, String.valueOf(fileLimit),
"hash"
, hash,
"list"
, String.valueOf(list),
"rev"
, rev,
"locale"
, session.getLocale().toString(),
"include_media_info"
, "true
"
};
String url_path = "/metadata/"
+ session.getAccessType() + path;
Map<String, Object> dirinfo =
(Map<String, Object>) RESTUtility.request(RequestMethod.GET,
session.getAPIServer(), url_path, DropboxAPI.VERSION, params, session);
return
new
PhotoEntry(dirinfo);
}
public
static
class
PhotoEntry extends
Entry {
public
String takenTime;
public
Double lat;
public
Double lon;
public
List<PhotoEntry> contentsPhoto;
public
PhotoEntry(Map<String, Object> map) {
super
(map);
Object json_photo_info = map.get("photo_info"
);
if
(json_photo_info != null
&& json_photo_info instanceof
JSONObject) {
takenTime = (String)((JSONObject)json_photo_info).get("time_taken"
);
Object json_lat_long = ((JSONObject)json_photo_info).get("lat_long"
);
if
(json_lat_long != null
&& json_lat_long instanceof
JSONArray) {
lat = (Double)((JSONArray) json_lat_long).get(0);
lon = (Double)((JSONArray) json_lat_long).get(1);
}
}
Object json_contents = map.get("contents"
);
if
(json_contents != null
&& json_contents instanceof
JSONArray) {
contentsPhoto = new
ArrayList<PhotoEntry>();
for
(Object entry: (JSONArray)json_contents) {
if
(entry instanceof
Map) {
contentsPhoto.add(new
PhotoEntry((Map<String, Object>) entry));
}
}
} else
{
contentsPhoto = null
;
}
}
}
使い方は,Android用Core APIの
DropboxAPIクラス
のmetadata()メソッドとほぼ同じです.
戻り値がEntryではなく新クラスPhotoEntryになっており,今回の追加属性を取り出せます.
参考