Flickrに登録されている写真で、現在地付近のものを検索して表示してみます。

対象の写真はジオタグを持っているものに限定。

現在地の測位にはGPS、地図表示にはGoogle Mapsを使ってみます。

初期画面はこんな感じ。

GPSと連動して、Google Maps上に現在地表示。



現在地表示のコードに関しては、Google Maps Android API V2で現在地の緯度・経度・標高を表示 を参照

Flickrの関する部分は別Activityで表示。

複数Activityの表示の仕方に関しては、Google Maps Android API V2覚書(地図処理系) の「情報表示・入力用のActivityを追加」を参照

FlickrInfoボタンをタップして、データを収集します。



Flickrの検索に関してはWebAPIを使います。

検索用のオプション(Argument)は、flickr.photos.search を参照

FlickrのAPIを使用するには、事前にキーを取得しておきます。

今回は、位置情報から検索するので、lat・lon・radiusを使い、ジオタグを持っている写真ということで、has_geoも使います。

検索結果はJSON形式で取得してみましょう。

ベースになるリクエストフォームは以下のような感じ(以下はダミー)。

この場合、10枚の検索を要求しています。radiusの単位は不明ですが多分km。

http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=ABCD1234&lat=35.1234&lon=135.1234&radius=1&has_geo=true&format=json&per_page=10&nojsoncallback=1"

以下の関数では、緯度・経度を引数にして、結果をJSONで返しています。

private String getPhotoDataByJson(double lat,double lon){
    HttpClient client = new DefaultHttpClient();
    HttpParams params = client.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 10000);
    HttpConnectionParams.setSoTimeout(params, 10000);
  
    // Uri作成
    URI uri = null;
    try {
        
        String apikey = "ABCD1234";
    
        uri = new URI("http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=" + apikey + "&lat=" + lat + "&lon=" + lon + "&radius=1&has_geo=true&format=json&per_page=10&nojsoncallback=1");
    
    } catch (URISyntaxException e) {
        Log.e("", e.toString());
    }
    //通信開始
    HttpUriRequest httpRequest = new HttpGet(uri);
 
    HttpResponse httpResponse = null;
    try {
        httpResponse = client.execute(httpRequest);
    } catch (ClientProtocolException e) {
        Log.e("", "httpRequest:" + e.toString());
    } catch (IOException e) {
        Log.e("", "httpRequest:" + e.toString());
    }
 
    if (httpResponse == null) {
        return "";
    }
 
    //jsonの取得
    String json = "";
 
    if (httpResponse != null
            && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
        HttpEntity httpEntity = httpResponse.getEntity();
        try {
            json = EntityUtils.toString(httpEntity);
        } catch (IOException e) {
            Log.e("", "EntityUtils:" + e.toString());
        }
    }
    
    
    return json;
}


FlickrのJSONをパースする場合、以下のようなコードになります。

写真表示に必要なデータを取得しておきます。

String json_data = getPhotoDataByJson(35.1234,135.1234);
            
try {
    JSONObject rootObject = new JSONObject(json_data);
    JSONObject photoObject = rootObject.getJSONObject("photos");
    JSONArray photoArray = photoObject.getJSONArray("photo");
    
    
     for (int i = 0; i < photoArray.length(); i++) {
              JSONObject jsonObject = photoArray.getJSONObject(i);
              
              String p_id = jsonObject.getString("id");
              String p_secret = jsonObject.getString("secret");
              String p_server = jsonObject.getString("server");
              String p_farm = jsonObject.getString("farm");
              String p_title = jsonObject.getString("title");

   }
     
 } catch (JSONException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
 }
        


取得したデータはダイアログでリストビュー表示。

何故か中国語のタイトルが多いのは、彼の地のから観光に来たおのぼりさんが、やたらアップしてるんだろうね(^^)。



タップして写真表示する場合

画像取得のリクエストフォーマットはこんな感じ。

http://farm{farm}.staticflickr.com/{server}/{id}_{secret}.jpg

コードはこんな感じ。ここではImageViewに表示してます。

private void setFlickr_photo(String p_farm,String p_server,String p_id,String p_seceret){
    //
    iv = new ImageView(this);
    
    Uri.Builder ub = new Uri.Builder();
    ub.scheme("http");
    ub.authority("farm" + p_farm + ".staticflickr.com");
    ub.path("/" + p_server + "/" + p_id + "_" + p_seceret + ".jpg");

    try {
        InputStream is = (InputStream) this.fetch(ub.build().toString());
        Drawable drawable = Drawable.createFromStream(is, "");
        is.close();
        iv.setImageDrawable(drawable);
    
    } catch (MalformedURLException e) {
        e.printStackTrace();
        
    } catch (IOException e) {
        e.printStackTrace();
        
    }
    
}




検索した写真はジオタグを持っています。

写真の位置情報を取得するには、APIキーと写真のidを使います。

リクエストフォーマットはこんな感じ。

ここで結果をXML(rest)で取得するようにしています。

http://www.flickr.com/services/rest/?method=flickr.photos.geo.getLocation&format=rest&api_key=ABCD1234&photo_id=123456789"

private String getGeoDataByXml(String api_key,String photo_id){
        
        String latlng = "";
    String uri = "http://www.flickr.com/services/rest/?method=flickr.photos.geo.getLocation&format=rest&lang=jp&api_key=" + api_key + "&photo_id=" + photo_id;
    try{
            XmlPullParser xmlPullParser = Xml.newPullParser();

            URL url = new URL(uri);
            URLConnection connection = url.openConnection();
            xmlPullParser.setInput(connection.getInputStream(), "UTF-8");

            int eventType;
    
    
           while ((eventType = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) {
                if (eventType == XmlPullParser.START_TAG) {
                    
                    
                    if ("location".equals(xmlPullParser.getName())){
                        String lat = xmlPullParser.getAttributeValue(null,"latitude");
                        String lon = xmlPullParser.getAttributeValue(null,"longitude");
                        
                        latlng = lat + "," + lon;
                    }
                }
            
            
            }
        }
    
    
    } catch (Exception e){
        Log.d("XmlPullParserSampleUrl", "Error");
    }
    
    return latlng;
    
    
}


で、写真をタップすると、写真の位置情報をMainActivityに渡して画面遷移し、マーカーを表示。



MainActivityへ遷移する方法や情報取得の方法は、Google Maps Android API V2覚書(地図処理系) の「情報表示・入力用のActivityを追加」を参照

private static final int MAINACTIVITY = 0;

Intent intent = new Intent(FlickrActivity.this,MainActivity.class);
intent.putExtra("FLICKR_VALUE", target_latlng);
startActivityForResult(intent, MAINACTIVITY);


マーカーの表示とかは、Google Maps Android API V2覚書 その2(画像処理系) の「マーカー(Markers)」を参照



Under construction




以下のように、何もデータが取得できない場合

原因として考えられるもの

●本当にデータが無い

●現在地の位置情報が得られていない

●Flickr.comのサイトがダウンしている

    (フリッカーのサイトは定期メンテナンスなどのためにアクセスできないことがあります)