【Android】ホットペッパーグルメAPIを利用して周辺の飲食店を表示する方法
どこ食べのバージョンアップ対応で現在地から飲食店の一覧を取得することがあったので備忘録📝
今回の実装内容
今回はリクルートWEBサービスのグルメサーチAPIを使用して、指定した緯度経度や条件から周辺の飲食店を取得してくる。🍜 APIの詳細は公式サイトをご覧ください🐶
1. APIキーの取得
ホットペッパーWEBサービスからAPIキーの申請を行う。 申請方法はリクルートWEBサービス(上URL)にアクセスし、[新規登録]ボタンからユーザー登録すれば取得することができる。
2. 実装
APIキーが取得できたら実際に実装していく。
2.1 権限の追加
インターネットを使用するため、AndroidManifest.xmlに権限を追加する。
<uses-permission android:name="android.permission.INTERNET" />
2.2 ホットペッパーAPIのパラメータクラスを作成
パラメータのクラスを作成する。
public class HotPepperGourmetSearch { private Double lat; // 緯度 private Double lng; // 経度 private int lunch; // ランチ営業有無 private int range; // 検索範囲距離 private int midnight_meal; // // 23時以降食事OK private ArrayList<String> keywordList; // キーワードのリスト private ArrayList<String> genreCdList; // ジャンルのリスト public Double getLat() { return lat; } public void setLat(Double lat) { this.lat = lat; } public Double getLng() { return lng; } public void setLng(Double lng) { this.lng = lng; } public int getLunch() { return lunch; } public void setLunch(int lunch) { this.lunch = lunch; } public int getRange() { return range; } public void setRange(int range) { this.range = range; } public int getMidnight_meal() { return midnight_meal; } public void setMidnight_meal(int midnight_meal) { this.midnight_meal = midnight_meal; } public ArrayList<String> getGenreCdList() { return genreCdList; } public void setGenreCdList(ArrayList<String> genreCdList) { this.genreCdList = genreCdList; } public ArrayList<String> getKeywordList() { return keywordList; } public void setKeywordList(ArrayList<String> keywordList) { this.keywordList = keywordList; } }
2.2 APIコール後の戻り値のクラスを作成
APIをコールしてから戻ってくる飲食店の情報を格納するクラスを作成する。
public class HotPepperGourmet { private String name; // 飲食店の名前 private String address; // 住所 private Double lat; // お店の緯度 private Double lng; // お店の経度 private String lunch; // ランチ有無 private String url; // お店のURL private String id; // お店コード public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Double getLat() { return lat; } public void setLat(Double lat) { this.lat = lat; } public Double getLng() { return lng; } public void setLng(Double lng) { this.lng = lng; } public String getLunch() { return lunch; } public void setLunch(String lunch) { this.lunch = lunch; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
2.3 APIを呼び出すクラスを作成
ActivityやFragmentからAPIをコールする処理を作成する。
/** * ホットペッパーグルメAPIの呼び出し */ public static void callHotPepperGourmetRestaurant(Activity activity, HotPepperGourmetSearch hotPepperGourmetSearch) { // URLの作成 // ジャンルの切り取り StringBuilder genreSb = new StringBuilder(); genreSb.append("&genre="); for (int i = 0; i < hotPepperGourmetSearch.getGenreCdList().size(); i++) { if (i > 0) { genreSb.append("&genre="); } String genreCd = hotPepperGourmetSearch.getGenreCdList().get(i); genreSb.append(genreCd); } // キーワードの切り取り StringBuilder keywordSb = new StringBuilder(); keywordSb.append("&keyword="); for (int i = 0; i < hotPepperGourmetSearch.getKeywordList().size(); i++) { if (i > 0) { keywordSb.append("&keyword="); } String keyword = hotPepperGourmetSearch.getKeywordList().get(i); keywordSb.append(keyword); } // URLの生成 StringBuilder urlStringBuilder = new StringBuilder(); urlStringBuilder.append("http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key="); urlStringBuilder.append(API_KEY); urlStringBuilder.append(genreSb.toString()); // 飲食店のジャンル urlStringBuilder.append("&midnight_meal="); // 23時以降食事OK urlStringBuilder.append(hotPepperGourmetSearch.getMidnight_meal()); urlStringBuilder.append(keywordSb.toString()); // キーワード urlStringBuilder.append("&lunch="); // ランチ営業 urlStringBuilder.append(hotPepperGourmetSearch.getLunch()); urlStringBuilder.append("&lat="); // 緯度 urlStringBuilder.append(hotPepperGourmetSearch.getLat()); urlStringBuilder.append("&lng="); // 経度 urlStringBuilder.append(hotPepperGourmetSearch.getLng()); urlStringBuilder.append("&range="); // 検索範囲距離 urlStringBuilder.append(hotPepperGourmetSearch.getRange()); urlStringBuilder.append("&count=100"); // 1ページあたりの取得数 urlStringBuilder.append("&format=json") // レスポンス形式 ; URL url = null; try { url = new URL(urlStringBuilder.toString()); // 非同期処理 new RestaurantAsync(activity).execute(url).get(3000, TimeUnit.MILLISECONDS); } catch (MalformedURLException e) { e.printStackTrace(); } catch (TimeoutException e) { e.printStackTrace(); mToastMessage = "接続がタイムアウトになったため、お店の情報を取得できませんでした"; Utils.toastMake(activity, mToastMessage); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } finally { // プログレスバーを閉じる if (RestaurantAsync.sProgressDialog != null && RestaurantAsync.sProgressDialog.isShowing()) { RestaurantAsync.sProgressDialog.dismiss(); } } Log.d(TAG, url.toString()); }
2.4 非同期処理とJSONのパース
非同期処理でHTTP通信を行い、飲食店の情報を取得する。戻りの形式はJSON形式で指定したので、 非同期処理後に戻ってきたJSONをパースする。
public class RestaurantAsync extends AsyncTask<URL, Void, String> { private Activity mActivity; private StringBuffer mBuffer = new StringBuffer(); private static final String TAG = "RestaurantAsync"; public static ProgressDialog sProgressDialog; /** * コンストラクタ * @param activity */ public RestaurantAsync(Activity activity) { mActivity = activity; } /** * 非同期処理の前処理 */ @Override protected void onPreExecute() { super.onPreExecute(); // プログレスバーを表示する sProgressDialog = new ProgressDialog(mActivity); sProgressDialog.setCancelable(false); // キャンセルさせない sProgressDialog.setMessage("お店を検索中..."); sProgressDialog.show(); } /** * 非同期処理 * @param url * @return */ @Override protected String doInBackground(URL... url) { HttpURLConnection con = null; URL urls = url[0]; try { con = (HttpURLConnection) urls.openConnection(); // JSONダウンロード con.setRequestMethod("GET"); // タイムアウト3秒 con.setConnectTimeout(3000); con.setReadTimeout(3000); // 接続 con.connect(); // レスポンスコードの確認 int resCd = con.getResponseCode(); if (resCd != HttpURLConnection.HTTP_OK) { // 接続NG throw new IOException("HTTP responseCode:" + resCd); } InputStream inputStream = con.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while (true) { line = reader.readLine(); if (line == null) { break; } mBuffer.append(line); } // クローズ inputStream.close(); reader.close(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { // 接続をクローズ con.disconnect(); } Log.d(TAG, mBuffer.toString()); return mBuffer.toString(); } /** * 非同期処理の後処理 * @param result */ @Override protected void onPostExecute(String result) { super.onPostExecute(result); try { // JSONをパースして各飲食店の情報を取得する JSONObject jsonObject = new JSONObject(result); JSONArray jsonArray = jsonObject.getJSONObject("results").getJSONArray("shop"); ArrayList<HotPepperGourmet> hotPepperGourmetArray = new ArrayList<>(); for (int i = 0; i < jsonArray.length(); i++) { HotPepperGourmet hotPepperGourmet = new HotPepperGourmet(); JSONObject json = jsonArray.getJSONObject(i); String id = json.getString("id"); // お店ID String name = json.getString("name"); // 店名 String address = json.getString("address"); // 住所 Double lat = json.getDouble("lat"); // 緯度 Double lng = json.getDouble("lng"); // 経度 String lunch = json.getString("lunch"); //ランチありなし String url = json.getJSONObject("urls").getString("pc"); // URL Log.d(TAG, "お店ID:" + id); Log.d(TAG, "店名:" + name); Log.d(TAG, "住所:" + address); Log.d(TAG, "緯度:" + lat.toString()); Log.d(TAG, "経度:" + lng.toString()); Log.d(TAG, "ランチありなし:" + lunch); Log.d(TAG, "URL:" + url); hotPepperGourmet.setId(id); hotPepperGourmet.setName(name); hotPepperGourmet.setAddress(address); hotPepperGourmet.setLat(lat); hotPepperGourmet.setLng(lng); hotPepperGourmet.setLunch(lunch); hotPepperGourmet.setUrl(url); hotPepperGourmetArray.add(hotPepperGourmet); } if (mActivity instanceof ConfirmAsyncListener) { // コールバック処理 ((ConfirmAsyncListener) mActivity).onRestaurantAsyncCallBack(hotPepperGourmetArray); } } catch (JSONException e) { e.printStackTrace(); } finally { // プログレスバーを閉じる if (sProgressDialog != null && sProgressDialog.isShowing()) { sProgressDialog.dismiss(); } } } interface ConfirmAsyncListener { void onRestaurantAsyncCallBack(ArrayList<HotPepperGourmet> hotPepperGourmetArray); } }
2.5 画面からの呼び出し
Activiyからコールしてみる。今回はonCreateで呼び出してみる。 コール後、onRestaurantAsyncCallBackにて、取得結果を確認することができる。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // HotPepperグルメAPIの呼び出し HotPepperGourmetSearch hotPepperGourmetSearch = new HotPepperGourmetSearch(); hotPepperGourmetSearch.setLat(mLat); // 画面でセットした緯度 hotPepperGourmetSearch.setLng(mLng); // 画面でセットした経度 hotPepperGourmetSearch.setLunch(mLunch); // 画面でセットしたランチ有無 hotPepperGourmetSearch.setRange(mRange); // 画面でセットした検索範囲距離 hotPepperGourmetSearch.setGenreCdList(mGenreCdList); // 画面でセットしたジャンルのリスト hotPepperGourmetSearch.setMidnight_meal(mMidnight_meal); // 画面でセットした23時以降食事OK hotPepperGourmetSearch.setKeywordList(mKeywordList); // 画面でセットしたキーワードのリスト // APIコール HotPepperUtils.callHotPepperGourmetRestaurant(MapsActivity.this, hotPepperGourmetSearch); } /** * ホットペッパーAPI呼び出し後のコールバック処理 * * @param hotPepperGourmetArray */ @Override public void onRestaurantAsyncCallBack(ArrayList<HotPepperGourmet> hotPepperGourmetArray) { // hotPepperGourmetArrayに飲食店の情報がセットされている }
では!