android - Zomato Android API 的模型类

标签 android json model zomato-api gson

你好,我正在尝试开发一个应用程序,我需要一个特定城市的餐馆列表。我正在尝试使用 Zomato API。从 https://developers.zomato.com/documentation 的文档中,我觉得/geocode 方法最适合我的需要。对此的示例响应如下所示 -

{"location": {
"entity_type": "",
"entity_id": 0,
"title": "Al Quoz",
"latitude": "25.1345620000",
"longitude": "55.2365110000",
"city_id": 51,
"city_name": "Dubai",
"country_id": 214,
"country_name": "UAE"
},
 "popularity": {
"popularity": "2.02",
"nightlife_index": "0.00",
"nearby_res": [
  "18274882",
  "206670",
  "18279664",
  "18264893",
  "208532",
  "210411",
  "207764",
  "18279641",
  "203695"
],
"top_cuisines": [
  "Indian",
  "Chinese",
  "Middle Eastern",
  "Pakistani",
  "Arabian"
],
"popularity_res": "100",
"nightlife_res": "10",
"subzone": "Al Quoz",
"subzone_id": 51301,
"city": "Dubai"
 },
 "link": "https://www.zomato.com/dubai/al-quoz-restaurants?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
  "nearby_restaurants": {
"1": {
  "restaurant": {
    "R": {
      "res_id": 18274882
    },
    "apikey": "--",
    "id": "18274882",
    "name": "Ice Lab",
    "url": "https://www.zomato.com/dubai/ice-lab-al-quoz?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "location": {
      "address": "Behind Al Quoz Pond Park, Meydan Road, Al Quoz, Dubai",
      "locality": "Al Quoz",
      "city": "Dubai",
      "city_id": 51,
      "latitude": "0.0000000000",
      "longitude": "0.0000000000",
      "zipcode": "",
      "country_id": 214
    },
    "cuisines": "Ice Cream",
    "average_cost_for_two": 85,
    "price_range": 2,
    "currency": "AED",
    "offers": [],
    "thumb": "https://b.zmtcdn.com/images/res_avatar_120_1x_new.png",
    "user_rating": {
      "aggregate_rating": "3.7",
      "rating_text": "Very Good",
      "rating_color": "5BA829",
      "votes": "30"
    },
    "photos_url": "https://www.zomato.com/dubai/ice-lab-al-quoz/photos#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "menu_url": "https://www.zomato.com/dubai/ice-lab-al-quoz/menu#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "featured_image": "",
    "has_online_delivery": 0,
    "is_delivering_now": 0,
    "deeplink": "zomato://r/18274882",
    "events_url": "https://www.zomato.com/dubai/ice-lab-al-quoz/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1"
  }
},
"2": {
  "restaurant": {
    "R": {
      "res_id": 206670
    },
    "apikey": "--",
    "id": "206670",
    "name": "Dubai Amaravathi",
    "url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "location": {
      "address": "Behind Old Grand Mall, Al Quoz, Dubai",
      "locality": "Al Quoz",
      "city": "Dubai",
      "city_id": 51,
      "latitude": "25.1465708500",
      "longitude": "55.2434410527",
      "zipcode": "",
      "country_id": 214
    },
    "cuisines": "Indian, North Indian, South Indian, Chinese",
    "average_cost_for_two": 50,
    "price_range": 2,
    "currency": "AED",
    "offers": [],
    "thumb": "https://b.zmtcdn.com/data/pictures/0/206670/a6140b8b6205d23c5fa123c7faeb7857_res_featured_thumb.png",
    "user_rating": {
      "aggregate_rating": "3.2",
      "rating_text": "Good",
      "rating_color": "9ACD32",
      "votes": "40"
    },
    "photos_url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz/photos#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "menu_url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz/menu#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "featured_image": "https://b.zmtcdn.com/data/pictures/0/206670/a6140b8b6205d23c5fa123c7faeb7857_featured_v2.png",
    "has_online_delivery": 1,
    "is_delivering_now": 1,
    "deeplink": "zomato://r/206670",
    "order_url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz/order?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "order_deeplink": "",
    "events_url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1"
  }
}
}
}
}

我正在尝试为此创建一个 Android 模型类,以便使用 GSON 解析响应。我的目标是简单地将“餐厅”对象放入列表中,以便我可以将它们提供给卡片 View 适配器。

目前这是我的模型的样子 -

public class RestaurantsZomato {

public LocationDetails location;
public Popularity popularity;
public String link;
public NearbyRestaurants nearby_restaurants;

public static class LocationDetails {
    public String entity_type;
    public int entity_id;
    public String title;
    public String latitude;
    public String longitude;
    public int city_id;
    public String city_name;
    public int country_id;
    public String country_name;
}

public static class Popularity {
    public String popularity;
    public String nightlife_index;
    public List<String> nearby_res;
    public List<String> top_cuisines;
    public String popularity_res;
    public String nightlife_res;
    public String subzone;
    public int subzone_id;
    public String city;
}

public static class NearbyRestaurants {

    public RestaurantDetails restaurant;
}

public class RestaurantDetails {

public Rest R;
public String apikey;
public String id;
public String name;
public String url;
public LocationDetails location;
public String cuisines;
public String average_cost_for_two;
public String price_range;
public String currency;
public List<String> offers;
public String thumb;
public UserRating user_rating;
public String photos_url;
public String menu_url;
public String featured_image;
public String has_online_delivery;
public String is_delivering_now;
public String deeplink;
public String events_url;
public String all_reviews_count;
public String photo_count;
public String phone_numbers;

public LocationDetails getLocation(){
    return location;
}

public static class LocationDetails {
    public String address;
    public String locality;
    public String city;
    public String latitude;
    public String longitude;
    public String zipcode;
    public String country_id;

    public String getAddress() {
        return address;
    }
}

  public static class UserRating {
    public static String aggregate_rating;
    public String rating_text;
    public String rating_color;
    public String votes;
}

public static class Rest {
    public float res_id;
}

在我的网络服务之后的 fragment 中,我像这样解析它 -

Ion.getDefault(getActivity()).configure().setLogging(getString(R.string.app_name), Log.DEBUG);
            Ion.with(getActivity())
                    .load("https://developers.zomato.com/api/v2.1/geocode?lat=25.12819&lon=55.22724")
                    .setHeader("user-key","my-user-key")
                    .asJsonObject()
                    .setCallback(new FutureCallback<JsonObject>() {
                        @Override
                        public void onCompleted(Exception e, JsonObject result) {

                                Log.d("FoodFragment", result.toString());
                                RestaurantsZomato r = (RestaurantsZomato) new Gson().fromJson(result.toString(), new TypeToken<RestaurantsZomato>(){}.getType());
                                JsonObject nearby_restaurants = result.get("nearby_restaurants").getAsJsonObject();
                                Log.d("RestDetails",nearby_restaurants.toString());

                                JsonObject rest = nearby_restaurants.get("1").getAsJsonObject();
                                Log.d("RestZomato", rest.toString());
                                JsonObject details = rest.get("restaurant").getAsJsonObject();
                                Log.d("RestZomato", details.toString());
                                RestaurantDetails ad = new Gson().fromJson(details, new TypeToken<RestaurantDetails>(){}.getType());

                                Set<Map.Entry<String, JsonElement>> objects =  nearby_restaurants.entrySet();
                                for (Map.Entry<String, JsonElement> entry : objects) {
                                    System.out.println(entry.getKey() + "/" + entry.getValue());
                                    if (entry.getValue() != null) {
                                        RestaurantDetails rd = new Gson().fromJson(entry.getValue(), RestaurantDetails.class);
                                        Log.d("simpletest",rd.getLocation().getAddress());
                                        sTrips.add(rd);
                                    }
                                }

                               adapter = new RestaurantAdapter(sTrips);
                                recyclerView.setAdapter(adapter);
                        }
                    });
        }

其中 sTrips 是 RestaurantDetails 类型的对象。我在 sTrips.add(rd) 行中遇到异常,因为 rd 为空。但是我不知道我做错了什么。请帮忙!

堆栈跟踪如下:

FATAL EXCEPTION: main
java.lang.NullPointerException
at majorproject.amity.smarttourist.fragments.FoodFragment$2.onCompleted(FoodFragment.java:161)
at majorproject.amity.smarttourist.fragments.FoodFragment$2.onCompleted(FoodFragment.java:131)
at com.koushikdutta.async.future.SimpleFuture.handleCallbackUnlocked(SimpleFuture.java:107)
at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:141)
at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:128)
at com.koushikdutta.ion.IonRequestBuilder$1.run(IonRequestBuilder.java:246)
at com.koushikdutta.async.AsyncServer$RunnableWrapper.run(AsyncServer.java:57)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)

更新 错误是行 Log.d("simpletest",rd.getLocation().getAddress());

调试了一下,发现rd的值确实为null。 Here is an image showing the debug

最佳答案

实际上你正在读取 "1"/"2" 的值,而你想在 for 循环中读取 restaurant 的值。检查答案。

    JsonObject rest = nearby_restaurants.get("1").getAsJsonObject();
    // Log.d("RestZomato", rest.toString());

    JsonObject details = rest.get("restaurant").getAsJsonObject();
    // Log.d("RestZomato", details.toString());
    RestaurantDetails ad = new Gson().fromJson(details, new TypeToken<RestaurantDetails>() {}.getType());

    Set<Map.Entry<String, JsonElement>> objects = nearby_restaurants.entrySet();

    for (Map.Entry<String, JsonElement> entry : objects) {
        System.out.println(entry.getKey() + "/" + entry.getValue());
        //entry.getValue() is the value of key "1"
        JsonObject ob=entry.getValue().getAsJsonObject();
        //you was reading value of "1" while you are suppose to read value of "restaurant"

        //get value from "restaurant" object

        if (ob != null) {
            //RestaurantDetails is created to read value of "restaurant"
            String restaurant=ob.get("restaurant").getAsJsonObject().toString(); 
            RestaurantDetails rd = new Gson().fromJson(restaurant, RestaurantDetails.class);
            System.out.println("Name "+rd.name);
            System.out.println(rd.getLocation().address);
        }
    }

关于android - Zomato Android API 的模型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37092517/

相关文章:

java - 将 Android 猜谜游戏限制为只能猜测 3 次

安卓 : ListVIew : change background onClick

android - 使用Gradle任务将productFlavor值写入文件

java - 将手机的 Activity 转换为平板电脑的 Fragment

java - 如何在 Java 中的 Firebase 数据中有嵌套集合的类中存储数据集合?

ruby-on-rails - 如何模拟说唱音乐的诠释

python - 如何在 django 模型中初始化与自身无关的 ManyToMany 字段(对象级别)?

javascript - Firebase 列表与对象

javascript - 如何在 JavaScript 中创建动态 json 对象

python - 当我想稍后填充数据时,django模型抛出IntegrityError : (1048, "Column ' xxx'不能为空”)