JSONを使ってみる

2011/02/16

以下のサイトなどを参考にしながら作成してみる。 [android] androidでBingでJSONで Android で JSON を使おう ~ 前編 ~ Android で JSON を使おう ~ 後編 ~

HTTP通信

まずインターネット接続を許可する為に、AndroidManifest.xmlに以下を記述する。 [java]

[/java] 次にHTTPリクエスト&レスポンスの実装 [java] SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register( new Scheme( HttpHost.DEFAULT_SCHEME_NAME, PlainSocketFactory.getSocketFactory(), 80 ) );

    HttpParams httpParams;
    httpParams= new BasicHttpParams();
    HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);

    httpClient = new DefaultHttpClient(
            new ThreadSafeClientConnManager(httpParams, schemeRegistry),
            httpParams
    );

[/java] HTTPリクエストは、まずSchemeRegistry()でプロトコルを設定する。 そして、BasicHttpParams()でヘッダ情報をパラメータ生成し、DefaultHttpClient()でリクエストする。 通信は、ThreadSafeClientConnManager()で非同期通信をしている。

[java] Uri.Builder uriBuilder = new Uri.Builder(); uriBuilder.scheme("http"); uriBuilder.authority("192.168.1.52"); uriBuilder.path("/api/areas");

    String uri = uriBuilder.toString();
    HttpUriRequest httpRequest = new HttpGet(uri);

    //HTTP Request送信
    HttpResponse response = null;
    try{
        response = httpClient.execute(httpRequest);
    } catch(Exception e) {
        setListItem(e.toString());
        return;
    }

[/java] schemeにプロトコル、authorityにホスト、pathにURLパスを記述する。 HttpClient.executeでリクエストするが、例外処理が必須。 こういうのは、Javaのきめ細かさですね。

テキストファイル取得

HTTPレスポンスからInputStreamReaderとBufferdReaderを使って行を読み、StringBuilderに追加する [java] StringBuilder json = new StringBuilder(); try{ HttpEntity entity = response.getEntity(); InputStream input = entity.getContent(); InputStreamReader reader = new InputStreamReader(input); BufferedReader bufReader = new BufferedReader(reader); String line; while((line = bufReader.readLine()) != null){ json.append(line); } } catch(IOException e) { setListItem("バッファ読み込み失敗"); return; } [/java]

JSON解析

import org.json.* [java] private void loadValues() { try{ JSONObject jsonRoot = new JSONObject(json.toString()); JSONArray jsonAreas = jsonRoot.getJSONArray("areas");

        List<String> items = new ArrayList<String>();
        int i;
        for (i = 0; i < jsonAreas.length(); i++){
            JSONObject jsonRslt = jsonAreas.getJSONObject(i);
            String title = jsonRslt.getString("area_code");
            String url = jsonRslt.getString("area_name");
            items.add(title + " " + url);
        }
        setListItems(items);
    } catch(JSONException e) {
        setListItem("JSON Error");
        return;
    }
}

private void setListItem(String item){
    ListView listView = (ListView)findViewById(R.id.ListView);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            new String[]{ item }
    );
    listView.setAdapter(adapter);
}

private void setListItems(List<String> items){
    ListView listView = (ListView)findViewById(R.id.ListView);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            items
    );
    listView.setAdapter(adapter);
}

[/java] JSONObjectのコンストラクタに、テキストデータをつっこむ。 生成したJSONObject以降は、各自データ構造によるが、上記の例の場合 getJSONArrayにキーを設定して、JSONArrayを取得している。

そしてforループで回して処理する。 この辺は、Objective-Cとは手順が違いますね。 むしろ原始的なコードなので取っつきやすいかもしれないが、少々回りくどい気もする。

リスト表示

まず、layout/main.xmlでレイアウトを作成しておく。 ※ListView android

次に、先ほど生成したJSONArrayデータをListViewにバインディングするが、Adapterが肝っぽいですね。 ArrayAdapterを生成して、ListViewにsetAdapterする。

android

と言う事で、参考ページのおかげもあってすんなり実装できました!

サンプルソース

[java] import android.app.Activity; import android.os.Bundle; import org.json.*; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.HttpVersion; import org.apache.http.params.HttpParams; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpUriRequest;

import android.view.View; import android.widget.ListView; import android.widget.ArrayAdapter; import android.widget.Button;

import android.net.Uri; import android.view.View.OnClickListener;

import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.InputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List;

public class Yosou extends Activity implements OnClickListener { String json; DefaultHttpClient httpClient;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //スキーマ登録
    SchemeRegistry schReg = new SchemeRegistry();
    schReg.register(
            new Scheme(
                    HttpHost.DEFAULT_SCHEME_NAME,
                    PlainSocketFactory.getSocketFactory(),
                    80
            )
    );

    //HTTPパラメータ設定
    HttpParams httpParams;
    httpParams= new BasicHttpParams();
    HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);

    //HTTPクライアント生成
    httpClient = new DefaultHttpClient(
            new ThreadSafeClientConnManager(httpParams, schReg),
            httpParams
    );

    Button loadButton = (Button)findViewById(R.id.loadButton);
    loadButton.setOnClickListener(this);
}

public void onClick(View v) {
    // URIを設定
    Uri.Builder uriBuilder = new Uri.Builder();
    uriBuilder.scheme("http");
    uriBuilder.authority("192.168.1.52");
    uriBuilder.path("/yosou/api/race_forecast_areas");

    String uri = uriBuilder.toString();
    HttpUriRequest httpRequest = new HttpGet(uri);

    //HTTP Request送信
    HttpResponse response = null;
    try{
        response = httpClient.execute(httpRequest);
    } catch(Exception e) {
        setListItem(e.toString());
        return;
    }

    // レスポンスコードを確認
    if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
        setListItem(
                String.format(
                        "Response Error code = %d",
                        response.getStatusLine().getStatusCode()
                )
        );
        return;
    }

    //JSON取得
    StringBuilder json = new StringBuilder();
    try{
        HttpEntity entity = response.getEntity();
        InputStream input = entity.getContent();
        InputStreamReader reader = new InputStreamReader(input);
        BufferedReader bufReader = new BufferedReader(reader);
        String line;
        while((line = bufReader.readLine()) != null){
            json.append(line);
        }
    } catch(IOException e) {
        setListItem("buffer Error");
        return;
    }

    // JSON解析
    try{
        JSONObject jsonRoot = new JSONObject(json.toString());
        JSONArray jsonAreas = jsonRoot.getJSONArray("areas");

        List<String> items = new ArrayList<String>();
        int i;
        for(i = 0; i < jsonAreas.length(); i++){
            JSONObject jsonRslt = jsonAreas.getJSONObject(i);
            String title = jsonRslt.getString("area_code");
            String url = jsonRslt.getString("area_name");
            items.add(title + " " + url);
        }
        setListItems(items);
    }
    catch(JSONException e){
        setListItem("JSON Error");
        return;
    }
    return;
}

private void setListItem(String item){
    ListView listView = (ListView)findViewById(R.id.ListView);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            new String[]{ item }
    );
    listView.setAdapter(adapter);
}

private void setListItems(List<String> items){
    ListView listView = (ListView)findViewById(R.id.ListView);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            items
    );
    listView.setAdapter(adapter);
}

} [/java]