Reputation: 107
I'm setting up a new android project and using retrofit, my retrofit function work correctly in emulator (NOX) and postman but when I try build my app in mobile device, retrofit always get into onFailure, can anyone give me solution ? My API is published on public hosting,
This is how I call retrofit
private APIInterface getInterfaceService() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
final APIInterface mInterfaceService = retrofit.create(APIInterface.class);
return mInterfaceService;
}
private void loginInterface(final String username, final String password){
APIInterface mApiService = this.getInterfaceService();
Call<Response> mService = mApiService.loginRequest(username,password);
mService.enqueue(new Callback<Response>() {
@Override
public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
if(response.body().getValue()==1){
Toast.makeText(Login.this,"Welcome",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(),HomePage.class);
startActivity(intent);
finish();
}else{
Toast.makeText(Login.this,"Invalid Username or Password",Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<Response> call, Throwable t) {
Toast.makeText(Login.this,t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
My Response
public class Response {
@SerializedName("value")
@Expose
private Integer value;
@SerializedName("result")
@Expose
private List<User> result = null;
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public List<User> getResult() {
return result;
}
public void setResult(List<User> result) {
this.result = result;
}
}
User Model
public class User {
@SerializedName("id")
@Expose
private String id;
@SerializedName("username")
@Expose
private String username;
@SerializedName("password")
@Expose
private String password;
@SerializedName("email")
@Expose
private String email;
@SerializedName("image")
@Expose
private Object image;
@SerializedName("point")
@Expose
private String point;
@SerializedName("reputation")
@Expose
private String reputation;
@SerializedName("role")
@Expose
private String role;
public User(String id, String username, String password, String email, Object image, String point, String reputation, String role) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.image = image;
this.point = point;
this.reputation = reputation;
this.role = role;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Object getImage() {
return image;
}
public void setImage(Object image) {
this.image = image;
}
public String getPoint() {
return point;
}
public void setPoint(String point) {
this.point = point;
}
public String getReputation() {
return reputation;
}
public void setReputation(String reputation) {
this.reputation = reputation;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
API Interface
public interface APIInterface {
@FormUrlEncoded
@POST("login.php")
Call<Response> loginRequest(@Field("username") String username,
@Field("password") String password);
}
I got this message from t.message 'CLEARTEXT communication to {my api url} not permitted by network security policy'
After I add this into manifest
android:usesCleartextTraffic="true"
I got this new one 'java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $'
My JSON respon is like this
{"value":1,"result":[{"id":"1","username":"username","password":"password","email":"email","image":null,"point":"0","reputation":"0","role":"2"}]}
This is my postman response
Upvotes: 0
Views: 1403
Reputation: 9056
Things you should follow whenever you are trying to use Retrofit Library in your project.
Your BASE URL should end with '/'.
String BASEURL = "http://www.xxxxxxxx.com/"
When you implementing the callback of retrofit. You need to check that your response gives you 200 by checking if(response.isSuccessful())
.
mService.enqueue(new Callback<Response>() {
@Override
public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
if(response.isSuccessful()){
if(response.body().getValue()==1){
Toast.makeText(Login.this,"Welcome",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(),HomePage.class);
startActivity(intent);
finish();
}else{
Toast.makeText(Login.this,"Invalid Username or Password",Toast.LENGTH_SHORT).show();
}
}else Toast.makeText(Login.this,response.errorBody().string(),Toast.LENGTH_SHORT).show(); // this will tell you why your api doesnt work most of time
}
@Override
public void onFailure(Call<Response> call, Throwable t) {
Toast.makeText(Login.this,t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
As I can see you are using Response class. The response has so many predefined objects and other libraries also have a name of Response. So, You have to check your imports file to cross verify that you are using your Response Object with your package name not others Response object.
As in your POSTMAN, you include 9 headers. You have to find out all 9 headers retrofit examples and add them in your API interface accordingly.
Note:- Follow these things, I think you will solve your problem by yourself.
Feel free to ask any questions after correct all the above instructions.
Upvotes: 0
Reputation: 1833
use this site to generate a correct response class in java
your response class should be like this :
public class Response implements Serializable
{
@SerializedName("value")
@Expose
private long value;
@SerializedName("result")
@Expose
private List<Result> result = null;
private final static long serialVersionUID = -7121130042760098410L;
public long getValue() {
return value;
}
public void setValue(long value) {
this.value = value;
}
public List<Result> getResult() {
return result;
}
public void setResult(List<Result> result) {
this.result = result;
}
}
-----------------------------------com.example.Result.java-----------------------------------
package com.example;
import java.io.Serializable;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Result implements Serializable
{
@SerializedName("id")
@Expose
private String id;
@SerializedName("username")
@Expose
private String username;
@SerializedName("password")
@Expose
private String password;
@SerializedName("email")
@Expose
private String email;
@SerializedName("image")
@Expose
private Object image;
@SerializedName("point")
@Expose
private String point;
@SerializedName("reputation")
@Expose
private String reputation;
@SerializedName("role")
@Expose
private String role;
private final static long serialVersionUID = 7267197789545166983L;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Object getImage() {
return image;
}
public void setImage(Object image) {
this.image = image;
}
public String getPoint() {
return point;
}
public void setPoint(String point) {
this.point = point;
}
public String getReputation() {
return reputation;
}
public void setReputation(String reputation) {
this.reputation = reputation;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
Upvotes: 0