API との json なやりとり
リハビリと材料精査を兼ねて Web な API とのやりとりなサンプルを書いて動作確認をしてみました。サンプルを書いて、というか以下なナニをパクッて作成。
ありがとうございます。
とりあえず
以下な要件を満たすべく手を入れてます。
- 面倒なので onCreate でデータ取得
- これは元ネタも同様な動作
- HTTP 通信は UIThread とは別なソレでやりとり
- 通信している間は ProgressDialog 出す
- データはリクルートさん (hotpepper) より取得
- HashMap に表示しない値も持ってみて一部のみ ListView にて表示
コードが以下となります。ちなみに JSONfunctions.java ですが、hotpepper が REST な API だとゆーことで HTTP メソドを GET した程度の修正しかしていません。おそらく汎用的に使えるものと思ってます。
Main.java が以下。
package com.pxr.tutorial.json; import java.util.ArrayList; import java.util.HashMap; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import com.pxr.tutorial.xmltest.R; import android.app.ListActivity; import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; public class Main extends ListActivity { private JSONObject mJson; private ArrayList<HashMap<String, String>> mylist; private Handler mHandler = new Handler(); private ProgressDialog mProgressDialog; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listplaceholder); mylist = new ArrayList<HashMap<String, String>>(); mProgressDialog = new ProgressDialog(this); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); mProgressDialog.setMessage("Please wait ..."); mProgressDialog.setCancelable(true); mProgressDialog.show(); new Thread(new Runnable() { @Override public void run() { //mJson = JSONfunctions.getJSONfromURL("http://api.geonames.org/earthquakesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&username=demo"); mJson = JSONfunctions.getJSONfromURL("http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=40[API-KEY]&lat=34.67&lng=135.52&range=5&order=4&format=json"); mHandler.post(new ListSetting()); } }).start(); } private class ListSetting implements Runnable { @Override public void run() { try{ JSONObject result = mJson.getJSONObject("results"); JSONArray earthquakes = result.getJSONArray("shop"); for(int i=0;i<earthquakes.length();i++){ HashMap<String, String> map = new HashMap<String, String>(); JSONObject e = earthquakes.getJSONObject(i); map.put("id", String.valueOf(i)); map.put("iid", e.getString("id")); map.put("name", e.getString("name")); map.put("lat", e.getString("lat")); map.put("lng", e.getString("lng")); mylist.add(map); } }catch(JSONException e) { Log.e("log_tag", "Error parsing data "+e.toString()); } ListAdapter adapter = new SimpleAdapter(Main.this, mylist , R.layout.main, new String[] { "name", "iid" }, new int[] { R.id.item_title, R.id.item_subtitle }); setListAdapter(adapter); final ListView lv = getListView(); lv.setTextFilterEnabled(true); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { @SuppressWarnings("unchecked") HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position); Toast.makeText(Main.this, "ID '" + o.get("name") + "' was clicked.", Toast.LENGTH_SHORT).show(); } }); mProgressDialog.dismiss(); } } }
最初、run の中で ProgressDialog#show とか呼び出してたりして駄目さ加減満点。JSONObject をバラすあたりも慣用的なヤり方を完全に忘れてて困りました。しかし JSON は取り回しが楽で良いですねぇ。早く Rails3 で json 戻す方法を調べたいものです。
そして以下が JSONfunction.java です。
package com.pxr.tutorial.json; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; public class JSONfunctions { public static JSONObject getJSONfromURL(String url){ InputStream is = null; String result = ""; JSONObject jArray = null; //http post try{ HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet(url); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); is = entity.getContent(); }catch(Exception e){ Log.e("log_tag", "Error in http connection "+e.toString()); } //convert response to string try{ BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); result=sb.toString(); }catch(Exception e){ Log.e("log_tag", "Error converting result "+e.toString()); } try{ jArray = new JSONObject(result); }catch(JSONException e){ Log.e("log_tag", "Error parsing data "+e.toString()); } return jArray; } }
余計な import があったりしますが、ご容赦下さい。タイミング的にアレですが、勉強会の材料にもなるな、と。