retrofit 2.3.0 how to handle nested json? - java

I am kinda of new to retrofit and i am not sure how to handle a nested json structure like this. if any one can help how to parse this type of structure . i would really i appreciate it . i have been stuck for days
{
"status": "ok",
"totalResults": 20,
"articles": [
{
"source": {
"id": null,
"name": "Bradenton.com"
},
"author": "By EILEEN NG Associated Press",
"title": "Malaysia says search for missing plane to end in June",
"description": "An official says the search for Malaysia Airlines Flight 370 by a U.S. company will likely end in June, as families of passengers marked the fourth anniversary of the plane's disappearance with hope that the world's biggest aviation mystery will be solved.",
"url": "http://www.bradenton.com/news/business/article203286984.html",
"urlToImage": "http://www.mcclatchy-wires.com/incoming/ukogzw/picture203286949/alternates/LANDSCAPE_1140/Malaysia_Missing_Plane_57970.jpg",
"publishedAt": "2018-03-03T09:42:00Z"
}
]
}

the http://www.jsonschema2pojo.org/ to convert your json to POJO and use that for retrofit 2.3

If you don't know how many classes you need to make ,just copy and paste your json here click here.
This will help you and make your work easy.

Create some pojos:
class Source {
String id;
String name;
}
class Article{
Source source;
String author;
String title;
String description;
String url;
String urlToImage;
String publishedAt;
}
class GetArticlesResponse{
String status;
int totalResults;
List<Article> articles;
}
And then pass GetArticlesResponse to your retrofit call.
import retrofit2.Response;
import retrofit2.Call;
public interface YourInterface {
#GET("your_end_point")
Call<Response<GetArticlesResponse>> getArticles();
}
or if you're using RX:
import retrofit2.Response;
import rx.Observable;
public interface YourInterface {
#GET("your_end_point")
Observable<Response<GetArticlesResponse>> getArticles();
}

MainClass.java
public class MainClass {
#SerializedName("status")
#Expose
private String status;
#SerializedName("totalResults")
#Expose
private Integer totalResults;
#SerializedName("articles")
#Expose
private List<Article> articles = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getTotalResults() {
return totalResults;
}
public void setTotalResults(Integer totalResults) {
this.totalResults = totalResults;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
}
Article.java
public class Article {
#SerializedName("source")
#Expose
private Source source;
#SerializedName("author")
#Expose
private String author;
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
#SerializedName("url")
#Expose
private String url;
#SerializedName("urlToImage")
#Expose
private String urlToImage;
#SerializedName("publishedAt")
#Expose
private String publishedAt;
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
}
Source.java
public class Source {
#SerializedName("id")
#Expose
private Object id;
#SerializedName("name")
#Expose
private String name;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Retrofit Interface
public interface YourInterface {
#GET("whatever api u are using")
Call<MainClass> getData(#Query("whatever key") String/int(whatever name)) //or leave blank
}

well when working with retrofit i suggest using Gson library with it which parses your json to an object type you should have created so first you should create an object representing your object from the response you get so it will be something like this in your case
public class Article implements Serializable {
private String author;
private String title;
private String description;
private String url;
private String urlToImage;
private String publishedAt;
private Source source;
public Story() {
}
public Story(String author,
String title,
Source source,
String description,
String url,
String urlToImage,
String publishedAt) {
this.author = author;
this.title = title;
this.source = source;
this.url = url;
this.urlToImage = urlToImage;
this.publishedAt = publishedAt;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
}
and similarly create your other class which is the Source class containing your Source object
public class Source implements Serializable {
private id id;
private String name;
public Source() {
}
public Source(int id,
String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
now in your retrofit api code you could do something like this
#GET("YOUR_ENDPOINT/")
Call<JsonObject> getArticles(... put your required fields here example ...#Query("token") String token);
and in your activity do something like this
List mArticleList = new ArrayList<>();
String mTotalResults = "";
UserApi service = ServiceGenerator.createService(UserApi.class);
Call<JsonObject> result = service.getArticles(token);
result.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.code() == 200) {
mArticleList = null;
JsonArray data = response.body().getAsJsonObject("data").getAsJsonArray("articles");
mArticleList = new Gson().fromJson(data.toString(), new TypeToken<List<Article>>(){}.getType());
mTotalResults = response.body().getAsJsonObject("data").getAsString("totalResults");
//if you want it as an integer you could do something like
int totalResults = Integer.parseInt(mTotalResults);
//... do what you want with your list
//...
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
//do what you have to do in case of error
}
});
}
hope this helps

Related

Getting null response when using Retrofit2

I am trying to login user and I am using Retrofit2 for networking but I am getting null response from the server though I have tested API in postman and it is showing response there but unable to fetch response in my app. I am unable to discover the cause of this error.
Here is an API URL. You can check response where email=digi#gmail.com and password=digi1234:
http://www.gurgaonhomeo.in/api_server/login
Below is my stack trace:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
This is my api response:
{
"data": [
{
"id": "7",
"username": null,
"mobile": "1254785698",
"email": "digi#gmail.com",
"image": "https://example.com",
"created_date": "2020-11-06",
"password": "dasdad324adad245435sffs34535",
"name": "Digi",
"address": "Hsbdbshbd",
"homoeo_practioner": "Yes"
}
],
"status": true,
"code": 200
}
These libraries I have used:
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
LoginRespose.java
public class LoginResponse {
#Expose
#SerializedName("code")
private String code;
#Expose
#SerializedName("data")
private List<LoginRes> data;
#Expose
#SerializedName("status")
private String status;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public List<LoginRes> getData() {
return data;
}
public void setData(List<LoginRes> data) {
this.data = data;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
LoginRes.java
public class LoginRes {
#SerializedName("address")
#Expose
private String address;
#SerializedName("created_date")
#Expose
private String createdDate;
#SerializedName("email")
#Expose
private String email;
#SerializedName("homoeo_practioner")
#Expose
private String homoeoPractioner;
#SerializedName("id")
#Expose
private String id;
#SerializedName("image")
#Expose
private String image;
#SerializedName("mobile")
#Expose
private String mobile;
#SerializedName("name")
#Expose
private String name;
#SerializedName("password")
#Expose
private String password;
#SerializedName("username")
#Expose
private String username;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getHomoeoPractioner() {
return homoeoPractioner;
}
public void setHomoeoPractioner(String homoeoPractioner) {
this.homoeoPractioner = homoeoPractioner;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
ApiService.java
#POST("login")
#FormUrlEncoded
Call<LoginResponse> logUser(#Field("email") String email,
#Field("password") String password);
Login.java
private void go(String mail,String pwd){
Retrofit retrofit = RetrofitClient.getInstance();
ApiService apiService = retrofit.create(ApiService.class);
apiService.logUser(mail,pwd).enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if(response.isSuccessful()){
prg.dismiss();
List<LoginRes> res = response.body().getData();
Toast.makeText(getApplicationContext(),res.get(0).getEmail(),Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
prg.dismiss();
Toast.makeText(getApplicationContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
Why am I getting null response from the server?
First check if response.body() is null. Then check if the data inside response is null or []. Then if those requirements are filled, then take the list and show the toast.

How do I deserialize a JSON representation containing array of objects using jackson?

I have the exact same JSON representation as here: https://newsapi.org/docs/endpoints/top-headlines
To deserialize this into java objects I have created a News and a Article class. News contains multiple Articles. So here are my classes:
News:
public class News {
private String status;
private int totalResults;
private Article[] articles;
public News() {
}
public News(String status, int totalResults, Article[] articles) {
this.status = status;
this.totalResults = totalResults;
this.articles = articles;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public int getTotalResults() {
return totalResults;
}
public void setTotalResults(int totalResults) {
this.totalResults = totalResults;
}
public Article[] getArticles() {
return articles;
}
public void setArticles(Article[] articles) {
this.articles = articles;
}
}
Article:
public class Article {
private String source;
private String author;
private String title;
private String description;
private String url;
private String imageUrl;
private String publishedAt;
private String content;
public Article() {
}
public Article(String source, String author, String title, String description, String url, String imageUrl,
String publishedAt, String content) {
this.source = source;
this.author = author;
this.title = title;
this.description = description;
this.url = url;
this.imageUrl = imageUrl;
this.publishedAt = publishedAt;
this.content = content;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
Now I am using the com.fasterxml.jackson.databind.ObjectMapper as following to deserialize the JSON representation into a News object:
ObjectMapper objectMapper = new ObjectMapper();
News news = objectMapper.readValue(response.toString(), News.class);
Here I am getting a com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
The problem apparently is the array of articles representated in JSON.
I have read about arrays deserialization in jackson but I found nothing about deserialization of objects that contain properties AND array of objects. https://www.baeldung.com/jackson-deserialization
How do I do this properly using the ObjectMapper? Am I missing out on something? Any help is appreciated, thanks!
Your source mapping is wrong,
the source field is of format
source": {
"id": "google-news",
"name": "Google News"
}
this can be replaced with
public class Source {
private String id;
private String name;
public Source() {}
public Source(String id, String name) {
this.id = id;
this.name = name;
}
}
and replace
private String source;
with
private Source source;
in the Article class

Json error for Java with Gson and retrofit [Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 70 path $.Data]

I am consuming an API about cryptocurrency news called CryptoCompare.
My problem is that I can't detect what my code error is.
The error is as follows -> com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 70 path $.Data
I copy the Json and my two classes to help me find the solution.
Json:
{
"Type": 100,
"Message": "News list successfully returned",
"Promoted": [
],
"Data": [
{
"id": "2940487",
"guid": "https://cointelegraph.com/news/australian-hacker-pleads-guilty-to-stealing-450-000-in-xrp-last-year",
"published_on": 1566590880,
"imageurl": "https://images.cryptocompare.com/news/cointelegraph/dj0O90McM86.png",
"title": "Australian Hacker Pleads Guilty to Stealing $450,000 in XRP Last Year",
"url": "https://cointelegraph.com/news/australian-hacker-pleads-guilty-to-stealing-450-000-in-xrp-last-year",
"source": "cointelegraph",
"body": "An Australian woman has pleaded guilty to stealing $450,000 in XRP",
"tags": "Altcoin|Australia|Fraud|Hackers|XRP|Tokens|Police",
"categories": "XRP|ICO|Altcoin",
"upvotes": "0",
"downvotes": "0",
"lang": "EN",
"source_info": {
"name": "CoinTelegraph",
"lang": "EN",
"img": "https://images.cryptocompare.com/news/default/cointelegraph.png"
}
},
]
Link of Api -> https://min-api.cryptocompare.com/data/v2/news/?lang=EN
Java Class News:
public class News {
#SerializedName("Type")
#Expose
private Integer type;
#SerializedName("Message")
#Expose
private String message;
#SerializedName("Data")
#Expose
private List<Article> articles = null;
#SerializedName("HasWarning")
#Expose
private Boolean hasWarning;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
public Boolean getHasWarning() {
return hasWarning;
}
public void setHasWarning(Boolean hasWarning) {
this.hasWarning = hasWarning;
}
Java Class Article:
public class Article {
#SerializedName("id")
#Expose
private String id;
#SerializedName("guid")
#Expose
private String guid;
#SerializedName("published_on")
#Expose
private Integer publishedOn;
#SerializedName("imageurl")
#Expose
private String imageurl;
#SerializedName("title")
#Expose
private String title;
#SerializedName("url")
#Expose
private String url;
#SerializedName("source")
#Expose
private String source;
#SerializedName("body")
#Expose
private String body;
#SerializedName("tags")
#Expose
private String tags;
#SerializedName("categories")
#Expose
private String categories;
#SerializedName("upvotes")
#Expose
private String upvotes;
#SerializedName("downvotes")
#Expose
private String downvotes;
#SerializedName("lang")
#Expose
private String lang;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
public Integer getPublishedOn() {
return publishedOn;
}
public void setPublishedOn(Integer publishedOn) {
this.publishedOn = publishedOn;
}
public String getImageurl() {
return imageurl;
}
public void setImageurl(String imageurl) {
this.imageurl = imageurl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTags() {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
public String getCategories() {
return categories;
}
public void setCategories(String categories) {
this.categories = categories;
}
public String getUpvotes() {
return upvotes;
}
public void setUpvotes(String upvotes) {
this.upvotes = upvotes;
}
public String getDownvotes() {
return downvotes;
}
public void setDownvotes(String downvotes) {
this.downvotes = downvotes;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
}
Interface to call Api:
public interface ApiInterface {
#GET("news")
Call<News> getNews(
#Query("lang") String lang,
#Query("api_key") String apiKey,
#Query("lTs") int lTs
);
Retrofit Class Builder
public static Retrofit getApiClient(String BASE_URL){
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.client(getUnsafeOkHttpClient().build())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
Fragment of Code when i call the api
private void LoadJson(){
swipeRefreshLayout.setRefreshing(true);
final ApiInterface apiInterface = ApiClient.getApiClient(ApiUtils.BASE_URL_NEWS).create(ApiInterface.class);
Call<News> call;
call = apiInterface.getNews("EN", ApiUtils.API_KEY,0);
call.enqueue(new Callback<News>() {
#Override
public void onResponse(Call<News> call, Response<News> response) {
if (response.isSuccessful() && response.body() != null){
articles.addAll(response.body().getArticles());
if (articles.size() - response.body().getArticles().size() == 0){
adapterNews.notifyDataSetChanged();
} else {
adapterNews.notifyItemRangeInserted(articles.size() - response.body().getArticles().size(), response.body().getArticles().size());
}
swipeRefreshLayout.setRefreshing(false);
progressBar.setVisibility(View.GONE);
} else {
Toast.makeText(getContext(), "No result", Toast.LENGTH_SHORT).show();
swipeRefreshLayout.setRefreshing(false);
progressBar.setVisibility(View.GONE);
}
}
#Override
public void onFailure(Call<News> call, Throwable t) {
Log.e(TAG, "ERROR API: " + t.getMessage() + " - " + t.getCause());
}
});
}
Any contribution is very helpful.
Thank you
FIXED THE PROBLEM WAS IN THE CALL
I notice that when you try query on api with wrong value like this
https://min-api.cryptocompare.com/data/v2/news/?lang=en
gives you json instead of array for data so this produce error
For fix and test instead of Locale.getDefault().getLanguage() use just "EN" and check the result
also for more help you can use this logging-interceptor

how to convert Source type converter to room

I am developing a news app and implemented but I am not able to convert model class to typeconverter below my model class
#Entity
#ForeignKey(entity = Source.class,parentColumns = "source", childColumns = "content")
public class Article {
#PrimaryKey
#SerializedName("source")
#Expose
#ColumnInfo(name ="source")
#TypeConverters(SourceTypeConverter.class)
private Source source;
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
#SerializedName("author")
#Expose
#ColumnInfo(name = "author")
private String author;
#SerializedName("title")
#Expose
#ColumnInfo(name = "title")
private String title;
#SerializedName("description")
#Expose
#ColumnInfo(name = "description")
private String description;
#SerializedName("url")
#Expose
#ColumnInfo(name = "url")
private String url;
#SerializedName("urlToImage")
#Expose
#ColumnInfo(name = "urlToImage")
private String urlToImage;
#SerializedName("publishedAt")
#Expose
#ColumnInfo(name = "publishedAt")
private String publishedAt;
#SerializedName("content")
#Expose
#ColumnInfo(name = "content")
private String content;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
below my SourceTypeConverter class
public class SourceTypeConverter {
#TypeConverter
public static Source ConvertSource(Source source){
return source == null ? null : new Source(source);
}
}
below Source.java
public class Source {
#SerializedName("id")
#Expose
private String id;
#SerializedName("name")
#Expose
private String name;
public Source(Source source) {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
below I am getting C:\Users\Edgar\Desktop\Sport News\app\src\main\java\edgar\yodgorbek\sportnews\model\Article.java:18: error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
private Source source;
below my database class
#Database(entities = {Article.class}, version = 1, exportSchema = false)
public abstract class SportNewsDatabase extends RoomDatabase {
public abstract SportNewsDao sportNewsDao();
}
According to our chat in linkedin I could say that you are very ungrateful man. Your problem that room can't convert file type Source that you have in model. So you need to create converter from Source class to type that sqlite supported.
According to your latest published code I could say that you try to do something wrong. You have two tables: Source and Article. And you want to store link to Source inside Article.
Delete your type converter
Read this http://androidkt.com/database-relationships/
In short you need to create foreign key for Source in Article. This is one-to-one relation.

APICall response fails to parse data

I need to Parse data from this URL https://newsapi.org/v1/articles?apiKey=6946d0c07a1c4555a4186bfcade76398&sortBy=top&source=bbc-news , but when i make an apicall, it never enters onResponse function, but always onFailure.
Always getting an "ERROR" Toast that is in onFailure.
I have tried changing BASE_URL and Query to several different options but it doesn't help. Maybe it is a problem with my object, but I can't find the mistake.
*****UPDATE*****: I changed my Object like said in comments, but still getting onFailure function.
MainActivity.java
public class MainActivity extends AppCompatActivity implements
OnItemClickListener{
public static final String EXTRA_TITLE="Title";
public static final String EXTRA_DESCRIPTION="Description";
public static final String EXTRA_URL="URL";
private RecyclerView recycler;
private RecyclerAdapter adapter;
private ArrayList<NewsCell> newsList;
private Call<List<NewsCell>> apiCall;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
newsList=new ArrayList<>();
setupRecycler();
setUpApiCall();
}
private void setUpApiCall(){
apiCall=NetworkUtils.getApiInterface().getNews(
"6946d0c07a1c4555a4186bfcade76398","top","bbc-news");
apiCall.enqueue(new Callback<List<NewsCell>>() {
#Override
public void onResponse(Call<List<NewsCell>> call,
Response<List<NewsCell>> response) {
if(response.isSuccessful() && response.body().size()!=0){
newsList.addAll(response.body());
adapter=new
RecyclerAdapter(MainActivity.this,newsList,MainActivity.this);
recycler.setAdapter(adapter);
}
else{
Toast.makeText(MainActivity.this, "No results",
Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<List<NewsCell>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Error",
Toast.LENGTH_SHORT).show();
}
});
}
private void setupRecycler() {
recycler=findViewById(R.id.recyclerView);
recycler.setLayoutManager(new LinearLayoutManager(this));
}
#Override
public void onItemClick(int position) {
Intent detailIntent=new Intent(this,NewsSingle.class);
NewsCell clickedItem=newsList.get(position);
detailIntent.putExtra(EXTRA_TITLE,clickedItem.getTitle());
detailIntent.putExtra(EXTRA_DESCRIPTION,clickedItem.getDescription());
detailIntent.putExtra(EXTRA_URL,clickedItem.getUrlToImage());
startActivity(detailIntent);
}
}
NetvorkUtils.java
public class NetworkUtils {
private static final String BASE_API="https://newsapi.org/v1/";
private static APIInterface apiInterface;
public static APIInterface getApiInterface(){
if(apiInterface==null){
Retrofit retrofit =new Retrofit.Builder()
.baseUrl(BASE_API)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiInterface=retrofit.create(APIInterface.class);
}
return apiInterface;
}
}
APIInterface.java
public interface APIInterface {
#GET("articles")
Call<List<NewsCell>> getNews(#Query("apiKey") String key, #Query("sortBy")
String sort,#Query("source") String source);
}
Article.java
public class Article {
#SerializedName("author")
#Expose
private String author;
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
#SerializedName("url")
#Expose
private String url;
#SerializedName("urlToImage")
#Expose
private String urlToImage;
#SerializedName("publishedAt")
#Expose
private String publishedAt;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
}
NewsCell.java
public class NewsCell {
#SerializedName("status")
#Expose
private String status;
#SerializedName("source")
#Expose
private String source;
#SerializedName("sortBy")
#Expose
private String sortBy;
#SerializedName("articles")
#Expose
private List<Article> articles = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getSortBy() {
return sortBy;
}
public void setSortBy(String sortBy) {
this.sortBy = sortBy;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
}
You are getting response like this
but in your model class NewsCell you are parsing only title ,description and urlToImage .which is inside articles array
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
#SerializedName("urlToImage")
#Expose
private String urlToImage;
So I would suggest you to copy whole your response . goto this site and generate your model class properly . and paste in into your NewsCell

Categories