2

I'm new to Retrofit and JSON and I don't really know how to parse the next json string:

{
"weight":[
    {   "bmi":21,
        "date":"2016-12-09",
        "fat":14.059000015258789,
        "logId":1222222222222,
        "source":"Aria",
        "time":"11:58:24",
        "weight":68
    },
    {   "bmi":21.83,
        "date":"2016-12-14",
        "logId":1222222222223,
        "source":"Aria",
        "time":"14:31:39",
        "weight":70.7
    }
]

}

I just want "weight" and "date" inside weight array. I've created a pojo class following some examples but it's not working. Also when trying it with my pojo class I couldn't get "weight" as a string (I'll then use it as a double) using .string().

(I know using .toString() shows something like "com.myPackage.MyPojo@xxxx").

For now, I have only been able to get the whole json through ResponseBody:

Call<ResponseBody>call = repository.getFitbitApi().getData();
               call.enqueue(new Callback<ResponseBody>() {
                   @Override
                   public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                       try {
                           System.out.println(response.body().string());
                       } catch (IOException e) {
                           e.printStackTrace();
                       }
                   }

                   @Override
                   public void onFailure(Call<ResponseBody> call, Throwable t) {

                   }
               });

What am I doing wrong? Here are my pojo classes, just an attempt...:

public class WeightList {

@SerializedName("weight")
@Expose

private ArrayList<WeightLogFitbit> weight = new ArrayList<>();

public WeightList(){

}

public ArrayList<WeightLogFitbit> getWeight() {
    return weight;
}


public void setWeight(ArrayList<WeightLogFitbit> weight) {
    this.weight = weight;
}

} And:

public class WeightLogFitbit {

//Variables in my JSON
@SerializedName("bmi")
@Expose
private String bmi;

@SerializedName("date")
@Expose
private String date;

@SerializedName("logId")
@Expose
private String logId;

@SerializedName("source")
@Expose
private String source;

@SerializedName("time")
@Expose
private String time;

@SerializedName("weight")
@Expose
private double weight;

@SerializedName("fat")
@Expose
private String fat;

public WeightLogFitbit(){}

//Getters and setters
public double getWeight() {
    return weight;
}

public void setWeight(double weight) {
    this.weight = weight;
}

public String getDate() {
    return date;
}
public void setDate(String date) {
    this.date = date;
}

public String getSource() {
    return source;
}
public void setSource(String source) {
    this.source = source;
}

public String getBmi(){
    return bmi;
}
public void setBmi(String bmi) {
        this.bmi = bmi;
    }

//
public String getFat(){
    return fat;
}
public void setFat(String fat) {
    this.fat = fat;
}


public String getTime() {
    return time;
}
    public void setTime(String time) {
        this.time = time;
    }
public String getLogId() {
    return logId;
}
public void setLogId(String logId) {
        this.logId = logId;
}

}

NOTE: I'm using RxSocialConnect library, which implements RxJava, Retrofit 2, OkHttp3 and gson, just in case. I did this following this example.

Rest of classes I'm using:

public class FitbitBtnActivity extends AppCompatActivity {

private FitbitRepository repository;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fitbit_btn);

        repository = new FitbitRepository();

        setUpFitbit();

    }


private void setUpFitbit() {
    findViewById(R.id.fitbitbtn).setOnClickListener(v ->
            RxSocialConnect.with(this, repository.fitbitService())
                    .subscribe(response -> response.targetUI().showToken(response.token()),
                            error -> showError(error))
    );

    findViewById(R.id.retrievebtn).setOnClickListener(v -> {
    Call<ResponseBody>call = repository.getFitbitApi().getData();
               call.enqueue(new Callback<ResponseBody>() {
                   @Override
                   public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                       try {
                           System.out.println(response.body().string());
                       } catch (IOException e) {
                           e.printStackTrace();
                       }
                   }

                   @Override
                   public void onFailure(Call<ResponseBody> call, Throwable t) {

                   }
               });

                //Original code from example in RxSocialConnect

                       /*.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Object>() {
                               @Override
                               public void call(Object user) {
                                   FitbitBtnActivity.this.showUserProfile(user.toString());
                               }
                           },
                        error -> FitbitBtnActivity.this.showError(error));*/

    }
    );
}

And:

public class FitbitRepository {


private final FitbitApiRest fitbitApi;

public FitbitRepository() {
    fitbitApi = initFitbitApiRest();
}

private FitbitApiRest initFitbitApiRest() {
    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new OAuth2Interceptor(FitbitApi20.class))
            .build();

    return new Retrofit.Builder()
            .baseUrl(FitbitApiRest.URL_BASE)
            .client(client)
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build().create(FitbitApiRest.class);
}



FitbitApiRest getFitbitApi() {
    return fitbitApi;
}



interface FitbitApiRest {
    String URL_BASE = "https://api.fitbit.com";

    @GET("myrequest.json")
    Call<ResponseBody> getData();
}

OAuth20Service fitbitService() {


    final String client_id = "xxxxx";
    final String client_secret = "1xxxxxxxxxxxxxxxxxx";
    final String redirect_uri = "http://example.com";
    final String permissions = "weight";

    return new ServiceBuilder()
            .apiKey(client_id)
            .apiSecret(client_secret)
            .callback(redirect_uri)
            .scope(permissions)
            .build(FitbitApi20.instance());
}

}

mmateo
  • 31
  • 5

1 Answers1

1

You need to add this to your dependencies:

compile 'com.squareup.retrofit2:converter-gson:your-version'

and then add a gson converter to your Retrofit instance like this:

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com")
.addConverterFactory(GsonConverterFactory.create())
.build();

and change your call in the api to return WeightList:

Call<WeightList> getData();
MoQ93
  • 341
  • 2
  • 12
  • Please, see my updated question. There's all the code I have. And I'm using `compile 'com.squareup.retrofit2:converter-gson:2.1.0'` – mmateo Jan 24 '17 at 19:18
  • you need to do the third step in my answer to get it automatically parsed then in your callback: response.body() should be your parsed object – MoQ93 Jan 24 '17 at 19:24
  • assuming my pojo classes are fine and after the changes you suggest, if I print response.body() in my callback I get somethig like "com.myPackage.MyPojo@xxxx". My biggest concern is to take weight as a variable I can use later. Sorry if this seems simple or I missunderstand some things, it's my first time with this. – mmateo Jan 24 '17 at 19:39
  • For the output: this because you don't override toString() in your pojo so the output is fine. try to implement toString() in your pojos.. you should be able to access the list and the returned objects without implementing toString() – MoQ93 Jan 24 '17 at 19:42
  • Okay, so implemented toString() in getWeight() - WeightList class. Printing response.body().getWeight() I got this: `[com.mypackage.WeightLogFitbit@8b964b5, com.mypackage.WeightLogFitbit@c9d374a]`which seems to be the 2 values I have in my json. – mmateo Jan 24 '17 at 19:53
  • Imagine I only have one: com.mypackage.WeightLogFitbit@8b964b5. Is this the variable I'm looking for to store? Shouldn't I be watching just a number? Thank you for your time, I really appreciate it. – mmateo Jan 24 '17 at 19:56
  • Your classes are subclasses of the Object class, so they inherit the implementation of toString() from it which is `getClass().getName() + '@' + Integer.toHexString(hashCode())` and that's why you got this output. To see a proper output: override toString() for WeightLogFitbit – MoQ93 Jan 24 '17 at 19:57
  • I understand. Tried to make changes, I still got WightLogFitbit@xxxx. Last question: storing a variable that way I assume I can play with it, can't I? What should I really do to show it on a TextView? – mmateo Jan 24 '17 at 20:10
  • You get a `WeightList` object in the respose body so you can do what do you wantwith it.. – MoQ93 Jan 25 '17 at 00:28
  • Finally I made it. Thank you very much for taking time and explaining a little bit the output, helped me a lot. – mmateo Jan 25 '17 at 11:32