SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Web APIで楽々Androidアプリ

Androidで作るお天気アプリと、JSONの基本

Web APIで楽々Androidアプリ(3)

  • X ポスト
  • このエントリーをはてなブックマークに追加

JSONデータの解析

 前回、天気情報を取得するWeb APIを解説しましたが、取得するデータがやや複雑なため、今回は、緯度と経度から都道府県を判別するシンプルなWeb APIを用いて、JSONデータの解析を説明します。

緯度と経度から都道府県を判別する

 緯度と経度から都道府県を判別するのは、Web APIを利用しなくても可能です。ただし、都道府県の位置データを参照する必要があり、けっこう面倒な処理になってしまいます。このような場合、Web APIを利用するのも一つの解決策です。Web APIであれば、とても短いコードで判定することができます。

 今回利用するWeb APIは、独立行政法人農業・食品産業技術総合研究機構から無料で提供されている「簡易逆ジオコーディングサービス」です。

 ちなみに、ジオコーディングとは、地名や住所から緯度・経度を求めることです。対して、緯度と経度から住所を求めることを、逆ジオコーディング(リバースジオコーディング)と呼びます。

 このWeb APIのURLは、http://www.finds.jp/ws/rgeocode.phpです。次に示すパラメータを用いて呼び出します。

パラメータ
パラメータ 意味
lat 検索対象点の緯度(北緯を正とする10進の度)
lon 検索対象点の経度(東経を正とする10進の度)
json JSON形式にする場合に指定

 例えば、皇居の緯度経度から住所を求めるには、次のようなURLです。

 結果は、次のようなJSONデータです。東京都千代田区千代田1、という住所が取得できていることが、なんとなく分かるのではないでしょうか。

{
  "status": 200,
  "result": {
    "prefecture": {
      "pcode": 13,
      "pname": "東京都"
    },
    "municipality": {
      "mname": "千代田区",
      "mcode": 13101
    },
    "local": [
      {
        "section": "千代田",
        "homenumber": "1",
        "distance": "155.674225497647",
        "latitude": "35.683934",
        "longitude": "139.75289"
      }
    ]
  },
  "argument": {
  },
  "meta": [
  ]
}

 ただし、実際のデータには、空白や改行はありません。ここでは理解しやすいように、JSONデータを整形しています(また、一部データを省略しています)。

 今回のアプリでは、このJSONデータを解析して、該当する地点の都道府県コードを取得します。

JSONデータを解析するには

 JSON(JavaScript Object Notation)とは、その名前のとおりJavaScriptの表記法を元にした、軽量なデータ記述言語です。さきほどのサンプルから分かるように、文字列のキー(フィールド)と値(プロパティ)のペアが基本となっています。

 XML同様JSONでも、多くのソフトウェアやプログラミング言語間でのデータ授受に利用されています。当然Android(Java)でも利用することができ、手軽にJSONが使えるようなオープンソースのライブラリが、いくつも公開されています。

 Android SDKにも、org.jsonパッケージとして標準的なライブラリが含まれています。ただこのライブラリは、解析処理スピードが遅く、APIもやや低レベルなものしかないため、あまり評判がよくありません。

 そこで今回は、パフォーマンスの点で評価の高いJackson(Jackson Java JSON-processor)を利用することにしました。Jackson以外では、JSONICや、google-gsonといったライブラリが有名です。

Jacksonとは

 Jacksonは、オープンソースのJSONライブラリで、AndroidのJavaでも利用することができます。

 Jacksonでは、おもに次の3種類の方法でJSONデータを扱うことが可能です。

  • ストーミングAPIでのアクセス(XMLのStAXに相当にする)
  • ツリーモデルでのアクセス(XMLのDOMに相当する)
  • JSONとJavaオブジェクトとのデータバインディング

 ストリーミングAPIは、データを先頭から順にアクセスする方法です。大きなデータであっても高速に動作しますが、特定のデータのみを取り出したい場合などには不向きです。そこで今回は、データ量も少ないので、ツリーモデルのAPIを利用することにします。

 このツリーモデルのAPIは、いったんすべてのJSONデータを読み込んで、オブジェクトのツリーを生成するものです。そのため、目的のノードを指定することで、後から自由にデータを参照することができます。

 なお、データバインディングとは、JSONオブジェクトをそのままJavaのオブジェクトに変換する方法です。JSONに含まれるデータをすべて使用する場合や、相互に変換する必要があれば便利ですが、今回は一部のデータしか参照しませんので、ツリーモデルAPIがもっともシンプルな実装になります。

Jacksonを利用する

 Jacksonを利用するには、ダウンロードページから、以下のライブラリ(jarファイル)をダウンロードして、あらかじめプロジェクトのlibsフォルダにコピーしておきます。

Jacksonライブラリファイル
ファイル名 内容
jackson-core-2.2.0.jar Coreライブラリ
jackson-databind-2.2.0.jar ツリーモデルライブラリ
jackson-annotations-2.2.0.jar データバインディング

 JacksonライブラリのツリーモデルAPIを利用するのは、とてもかんたんです。以下のコードは、先ほどの住所情報が含まれるJSON文字列を解析して、住所コードを求めるものです。

ParseJson.javaの一部]
class ParseJson {

    protected String content;

    protected JsonNode getJsonNode(String str) {
        try {
            // JSON文字列を、JsonNodeオブジェクトに変換する(1)
            return new ObjectMapper().readTree(str);
        } 
        catch (IOException e) {
            Log.d(getClass().getName(), e.getMessage());
        }
        return null;
    }
    ~中略~
}
ParseFindsjp.javaの一部
// JSON文字列から都道府県コードを取得する
public class ParseFindsjp extends ParseJson {

    @Override
    public void loadJson(String str) {

        JsonNode root = getJsonNode(str);
        if (root != null){

            // ツリーオブジェクトから都道府県コードを取得する(2)
            this.content = root.path("result").path("prefecture")
                                                    .path("pcode").asText();
        }
    }
}

 解析処理を、基本クラスと派生クラスに分割しています。今回は2種類のJSONデータを解析する必要がありますので、共通の処理を基本クラスとしてまとめました。

 基本クラスでは、JSON文字列をJsonNodeオブジェクトに読み込み(getJsonNodeメソッド)、派生したクラスのメソッドで、そのツリーを解析しています。

 オブジェクトのツリーを構築するには、Jacksonライブラリで提供されるObjectMapperというクラスを利用します(1)。このクラスのreadTreeメソッドは、引数のJSON文字列からツリーを生成するメソッドです。戻り値は、ツリー構造のルートを示すJsonNodeというオブジェクトになっています。

 JsonNodeオブジェクトは、複数の子ノードと、それにひもづいたフィールドの情報を保持しています。

 このサンプルで取得している都道府県コードは、以下のようなノードに含まれています。

result ─ prefecture ┬ pcode: 13
                     └ pname: 東京都

 JsonNodeクラスのpathメソッドは、指定のノードのオブジェクトを返すメソッドです。このメソッドではメソッドチェーンが使えますので、直感的に理解しやすい実装が可能です(2)。asText()メソッドは、プロパティを文字列として取得します。ここでは、13という東京都のコードを、文字列として取得しています。

 なおpathメソッドでは、存在しないノードを指定した場合、MissingNodeというオブジェクトを返します。このオブジェクトは、JsonNodeのメソッドをすべて実装していますので、どのようなデータに対しても例外が発生せず、メソッドチェーンが利用可能です。

次のページ
最後に

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Web APIで楽々Androidアプリ連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7352 2013/09/10 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング