将 Zomato Api 与 Retrofit 结合使用

Using Zomato Api with Retrofit

我正在尝试使用 RetroFit 从 Zomato Api 检索餐厅列表,但我只收到空响应,而且找不到我所做的 wrong.I 已经尝试更改 @Header@Query 并将响应类型从 ApiResponse 更改为 List<Restaurant> 但问题仍然存在。

这是调用 Zomato 的 /search 端点的响应示例Api

"results_found": 4072,
  "results_start": 0,
  "results_shown": 1,
  "restaurants": [
    {
      "restaurant": {
        "R": {
          "has_menu_status": {
            "delivery": -1,
            "takeaway": -1
          },
          "res_id": 17836294,
          "is_grocery_store": false
        },
        "apikey": "75be9f9e2239fe637bf9cb1b46979d91",
        "id": "17836294",
        "name": "Cervejaria Meia Banana",
        "url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
        "location": {
          "address": "Avenida do Infante Dom Henrique, 178, Coimbrões, Vila Nova de Gaia",
          "locality": "Coimbrões",
          "city": "Porto",
          "city_id": 311,
          "latitude": "41.1213507499",
          "longitude": "-8.6152520031",
          "zipcode": "",
          "country_id": 164,
          "locality_verbose": "Coimbrões, Porto"
        },
        "switch_to_order_menu": 0,
        "cuisines": "Portuguese, Finger Food, Petiscos",
        "timings": "08:00 to 24:00 (Mon, Tue, Wed, Thu, Sun), 08:00 to 02:00 (Fri-Sat)",
        "average_cost_for_two": 35,
        "price_range": 3,
        "currency": "€",
        "highlights": [
          "Lunch",
          "Debit Card",
          "Breakfast",
          "Dinner",
          "Indoor Seating",
          "Wine",
          "Fullbar",
          "Beer"
        ],
        "offers": [],
        "opentable_support": 0,
        "is_zomato_book_res": 0,
        "mezzo_provider": "OTHER",
        "is_book_form_web_view": 0,
        "book_form_web_view_url": "",
        "book_again_url": "",
        "thumb": "https://b.zmtcdn.com/data/res_imagery/17836294_RESTAURANT_2d9d944dfca0415414fdfeca7522c396.jpg?fit=around%7C200%3A200&crop=200%3A200%3B%2A%2C%2A",
        "user_rating": {
          "aggregate_rating": "3.4",
          "rating_text": "Average",
          "rating_color": "CDD614",
          "rating_obj": {
            "title": {
              "text": "3.4"
            },
            "bg_color": {
              "type": "lime",
              "tint": "500"
            }
          },
          "votes": 24
        },
        "all_reviews_count": 10,
        "photos_url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop",
        "photo_count": 30,
        "menu_url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop",
        "featured_image": "https://b.zmtcdn.com/data/res_imagery/17836294_RESTAURANT_2d9d944dfca0415414fdfeca7522c396.jpg",
        "has_online_delivery": 0,
        "is_delivering_now": 0,
        "store_type": "",
        "include_bogo_offers": true,
        "deeplink": "zomato://restaurant/17836294",
        "is_table_reservation_supported": 0,
        "has_table_booking": 0,
        "events_url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
        "phone_numbers": "22 3792953",
        "all_reviews": {
          "reviews": [
            {
              "review": []
            },
            {
              "review": []
            },
            {
              "review": []
            },
            {
              "review": []
            },
            {
              "review": []
            }
          ]
        },
        "establishment": [
          "Casual Dining"
        ],
        "establishment_types": []
      }
    }
  ]
}

Api 界面

public interface ZomatoApi {
    @GET("search")
    Call<ApiResponse> getNearbyRestaurants(@Query("lat") double lat, @Query("lon") double lon,
                        @Query("count") int count,@Query("radius") double radius, @Header("api_key") String apiKey);
}

Api响应Class

package com.cmuteam.app;

import java.util.List;

public class ApiResponse {
        private String results_found;
        private String  results_start;
        private String results_shown;
        private List<Restaurant> restaurants;

    public ApiResponse(String results_found, String results_start, String results_shown, List<Restaurant> restaurants) {
        this.results_found = results_found;
        this.results_start = results_start;
        this.results_shown = results_shown;
        this.restaurants = restaurants;
    }

    public String getResults_found() {
        return results_found;
    }

    public String getResults_start() {
        return results_start;
    }

    public String getResults_shown() {
        return results_shown;
    }

    public List<Restaurant> getRestaurants() {
        return restaurants;
    }
}

餐厅Class

package com.cmuteam.app;

public class Restaurant {
    private String id;
    private String name;
    Location location;

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Location getLocation() {
        return location;
    }

    public Restaurant(String id, String name, Location location) {
        this.id = id;
        this.name = name;
        this.location = location;
    }
}

地点Class

public class Location {
    private String address;
    private String latitude;
    private String longitude;

    public Location(String address, String latitude, String longitude) {
        this.address = address;
        this.latitude = latitude;
        this.longitude = longitude;
    }

    public String getAddress() {
        return address;
    }

    public String getLatitude() {
        return latitude;
    }

    public String getLongitude() {
        return longitude;
    }

我进行 Api 调用的片段

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getContext();
        mAuth = FirebaseAuth.getInstance();
        restaurantsList= new ArrayList<>(50);
        getApi().getNearbyRestaurants(41.12108,-8.615718100000002,20,10000,"75be9f9e2239fe637bf9cb1b46979d91")
                .enqueue(new Callback<ApiResponse>() {
                    @Override
                    public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
                        List<Restaurant> restaurants=response.body().getRestaurants();
                        mAdapter = new RestaurantAdapter(context, restaurantsList);
                        RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
                        mRecyclerView.addItemDecoration(itemDecoration);
                        for (int i = 0; i < restaurants.size(); i++) {
                            restaurantsList.add(new Restaurant(restaurants.get(i).getId(),restaurants.get(i).getName(),restaurants.get(i).getLocation()));
                            mAdapter.notifyItemInserted(i);
                        }
                    }

                    @Override
                    public void onFailure(Call<ApiResponse> call, Throwable t) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                        builder.setMessage("Couldn´t find any nearby restaurants");
                        AlertDialog mDialog = builder.create();
                        mDialog.show();
                    }
                });
    }

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View mContentView = inflater.inflate(R.layout.poi_list, container,false);
        mRecyclerView = mContentView.findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(mContentView.getContext()));
        mRecyclerView.setAdapter(mAdapter);
        return mContentView;
    }

    private Retrofit getRetrofit(){
        return new Retrofit.Builder()
                .baseUrl("https://developers.zomato.com/api/v2.1/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    private ZomatoApi getApi(){
        return  getRetrofit().create(ZomatoApi.class);
    }

授权 header 称为“user-key”,而不是 zomato 文档中提到的“api_key”。