How to get https status code in Retrofit RxJava Android? - android

Before I always used retrofit to load data. It's very easy to handle or get status code of the response.
But now I want to use Retrofit with RxJava but I don't know how to handle or get the https status code of the response in onNext method.
progressDialog.show();
Observable<ResponseData> observable = apiService.getData();
compositeDisposable.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<ResponseData>() {
#Override
public void onNext(ResponseData responseData) {
Log.e("pppp", "onNext: " + responseData.toString());
}
#Override
public void onError(Throwable e) {
progressDialog.dismiss();
Log.e("pppp", "onError: " + e.getMessage());
}
#Override
public void onComplete() {
progressDialog.dismiss();
Log.e("pppp", "onComplete");
}
})
);
Everyone, please help me to solve this problem.
Thanks!

You should wrap your ResponseData inside Response as
Observable<Response<ResponseData>> observable = apiService.getData();
Then inside onNext
#Override
public void onNext(Resposne<ResponseData> response) {
int statusCode = response.code();
}
and for error
#Override
public void onError(Throwable e) {
((HttpException) e).code();
}

responseData.code gives you the status code
int statusCode = responseData.code();

for getting status
Observable<ResponseData> observable = apiService.getData();
compositeDisposable.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<ResponseData>() {
#Override
public void onNext(ResponseData responseData) {
int statusCode = responseData.code();
// here you get your status code
Log.e("statusCode ", "onNext: " + statusCode );
}
#Override
public void onError(Throwable e) {
progressDialog.dismiss();
Log.e("pppp", "onError: " + e.getMessage());
}
#Override
public void onComplete() {
progressDialog.dismiss();
Log.e("pppp", "onComplete");
}
})
);

Related

Why does my progress bar not working properly?

I've been building an app which has Log In functionality. I've tested it but every time i tried to Log In, the progress bar disappeared to quickly (like a quarter second or something), and the response i get from the server is like about 2 seconds after the progress bar disappeared. Here are some of my codes.
My LoginTask inner class :
private class LoginTask extends AsyncTask<Account, Void, Account>{
private String getUsername = username.getText().toString();
private String getPassword = password.getText().toString();
#Override
protected void onPreExecute() {
super.onPreExecute();
//showDialog();
progressBar.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Account account) {
super.onPostExecute(account);
//dismissDialog();
progressBar.setVisibility(View.GONE);
}
#Override
protected Account doInBackground(Account... accounts) {
getLogin(getUsername, getPassword);
return null;
}
}
Login Retrofit call to server
private void getLogin(String email, String password) {
Call<LoginAuth> call = userService.getLogin(email, password);
call.enqueue(new Callback<LoginAuth>() {
#Override
public void onResponse(Call<LoginAuth> call, Response<LoginAuth> response) {
try {
if (response.body().getToken_type().equals("xxx")) {
Log.i(TAG, "getLogin, Authorized access");
Log.i(TAG, "getLogin, access_token: " + response.body().getAccess_token().toString());
Log.i(TAG, "getLogin, expires_at" + response.body().getExpires_at().toString());
} else {
Log.e(TAG, "getLogin, Unauthorized access" + response.body().getToken_type().toString());
}
} catch (Exception e) {
Log.e(TAG, "getLogin exception " + e.getMessage());
}
}
#Override
public void onFailure(Call<LoginAuth> call, Throwable t) {
Log.e(TAG, "getLogin, onFailure : " + t.getMessage());
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(LoginActivity.this, "Unable to Log In :(", Toast.LENGTH_SHORT).show();
}
});
}
});
}
I want it to work like when the response is fetched, that's the time the progress bar disappeared (not instantly). Did i do something wrong with the code?
As you are using retrofit, there is no necessity to call your api in separate asynctask as retrofit manages it asynchronously. what you should do is show your progressbar before you call api and dismiss it in onResponse and onFailure both. so your code would change to something like below.
private void getLogin(String email, String password) {
progressBar.setVisibility(View.VISIBLE);
Call<LoginAuth> call = userService.getLogin(email, password);
call.enqueue(new Callback<LoginAuth>() {
#Override
public void onResponse(Call<LoginAuth> call, Response<LoginAuth> response) {
progressBar.setVisibility(View.Gone);
//rest of your code
}
#Override
public void onFailure(Call<LoginAuth> call, Throwable t) {
Log.e(TAG, "getLogin, onFailure : " + t.getMessage());
progressBar.setVisibility(View.Gone);
//rest of your code
}
});
}

onComplete is not getting called when returning response as Flowable

I am trying to make webservie call using retrofit and rxjava 2. i was exploring two different approach to use RxJava2. problem is i am getting response whene i use Observable but it is not working with Flowable. Logs are not getting printed when using Flowable i tried to debug it but its not going inside onNext or onComplete or onError. only onSubscribe gets executed.
1) using observable as return type
new WebRequestManager().getContactObservable(userRequest)
.subscribe(new Observer<ResponseData>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(ResponseData responseData) {
Log.e(TAG , "data "+responseData.getStatus());
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
Log.e(TAG , "data complete");
}
}
);
2) Using flowable as return type
new WebRequestManager().getContactFlowable(userRequest)
.subscribe(new Subscriber<ResponseData>() {
#Override
public void onSubscribe(Subscription s) {
Log.e(TAG , "contact subscription ");
}
#Override
public void onNext(ResponseData responses) {
Log.e(TAG , "contact onNext ");
}
#Override
public void onError(Throwable t) {
}
#Override
public void onComplete() {
Log.e(TAG , "contact onComplete ");
}
});
Rest contact retrofit api
public interface ContactApi {
#POST(WebRequest.GET_CONTACTS)
Flowable<ResponseData> getContactFlowable(#Body UserRequest userRequest);
#POST(WebRequest.GET_CONTACTS)
Observable<ResponseData> getContactObservable(#Body UserRequest userRequest);
}
call to webservice
public Flowable<ResponseData> getContactsData(UserRequest userRequest){
return webRequest.getWebClient().create(ContactApi.class).getContacts(userRequest);
}
public Observable<ResponseData> getContact(UserRequest userRequest){
return webRequest.getWebClient().create(ContactApi.class).getContact(userRequest);
}
getting retrofit instance
public static Retrofit getWebClient(){
//if(okHttpClient == null)
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(120,TimeUnit.SECONDS)
.readTimeout(120,TimeUnit.SECONDS)
.writeTimeout(120,TimeUnit.SECONDS)
.addInterceptor(new WebRequestInterceptor("\"application/json\""))
.build();
// if(client == null)
client = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(LoganSquareConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
return client;
}
With Subscribers, you have to call request to get items:
new WebRequestManager().getContactFlowable(userRequest)
.subscribe(new Subscriber<ResponseData>() {
#Override
public void onSubscribe(Subscription s) {
Log.e(TAG , "contact subscription ");
s.request(Long.MAX_VALUE); // <---------------------------------
}
#Override
public void onNext(ResponseData responses) {
Log.e(TAG , "contact onNext ");
}
#Override
public void onError(Throwable t) {
}
#Override
public void onComplete() {
Log.e(TAG , "contact onComplete ");
}
});
See also DisposableSubscriber with its example.

enqueue multiple GET request when using nested retrofit 2.0

I am using Retrofit 2.0 to make api calls with nesting multiple requests. All api's works fine individually.
But when i nested all retrofit, First request execute perfectly but after that when i register second request it's not callback in enqueue method (i.e. it's directly returning null without inserting enqueue's inner methods like onResponse, onFailure)
My Code :-
public class Main2Activity extends AppCompatActivity {
Gson gson;
JSONObject jsonResult=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
gson=new GsonBuilder().create();
firstRequest(); //-- First retrofit request
}
private void firstRequest() {
Retrofit retrofit=new Retrofit.Builder().baseUrl(getResources().getString(R.string.Api_Url)).addConverterFactory(GsonConverterFactory.create(gson)).build();
CityRetailsApi service = retrofit.create(CityRetailsApi.class);
Call call_first= service.getMainCatFlag();
call_first.enqueue(new Callback() {
#Override
public void onResponse(Call call, Response response) {
Log.d("MainActivity", "Status Code = " + response.code());
if (response.isSuccessful()){
MainCatFlag result = (MainCatFlag) response.body(); //-- Get First request response
JSONObject json2nd = secondRequest(); //-- Second request
}
}
#Override
public void onFailure(Call call, Throwable t) {
Log.d("MainActivity", "Error");
}
});
}
private JSONObject secondRequest() {
try {
Retrofit retrofit=new Retrofit.Builder().baseUrl(getResources().getString(R.string.Api_Url)).addConverterFactory(GsonConverterFactory.create(gson)).build();
CityRetailsApi service = retrofit.create(CityRetailsApi.class);
Call call_second= service.getMainCat();
call_second.enqueue(new Callback() {
#Override
public void onResponse(Call call2, Response response1) {
Log.d("MainActivity", "Status Code = " + response1.code());
if (response1.isSuccessful()) {
MainCat result = (MainCat) response1.body();
if (result.getSuccess()==1)
{
try {
jsonResult= new JSONObject(new Gson().toJson(result));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
#Override
public void onFailure(Call call, Throwable t) {
Log.d("MainActivity", "Error");
}
});
}catch (Exception e){
Log.d("MainActivity", "Error= " + e);
}
return jsonResult;
}
}
In above code firstRequest() executed correctly and proving response but the secondRequest (inside firstRequest() enqueue method) not working fine. Not showing any error, success message in console. Can any one please help me to override this problem.
If any problem in my code, please let me know.
Thank you in advance.
You made a mistake that when you using retrofit enquene,it's called asynchronously, so you can't get the result outside of the callback method!
So, you should process your result inside the onResponse method like this:
private void secondRequest() {
try {
call_second.enqueue(new Callback() {
#Override
public void onResponse(Call call2, Response response1) {
Log.d("MainActivity", "Status Code = " + response1.code());
if (response1.isSuccessful()) {
MainCat result = (MainCat) response1.body();
if (result.getSuccess()==1)
{
try {
jsonResult= new JSONObject(new Gson().toJson(result));
// process your jsonResult here
...
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
#Override
public void onFailure(Call call, Throwable t) {
Log.d("MainActivity", "Error");
}
});
}catch (Exception e){
Log.d("MainActivity", "Error= " + e);
}
}

Android okhttp Async progressdialog

I want to add progressdialog into okhttp (asynchronous, not AsyncTask)
but i got this error:
Error: Can't create handler inside thread that has not called
Looper.prepare()
How to fix it in a proper way? I want to be sure that is the best way to do this.
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d("TAG_response", " brak neta lub polaczenia z serwerem ");
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
progress = ProgressDialog.show(SignUp.this, "dialog title",
"dialog message", true);
try {
Log.d("TAGx", response.body().string());
if (response.isSuccessful()) {
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
//System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
Log.d("TAG2", responseHeaders.name(i));
Log.d("TAG3", responseHeaders.value(i));
}
Log.d("TAG", response.body().string());
progress.dismiss();
main_activity();
}
else{
progress.dismiss();
alertUserAboutError();
}
}
catch (IOException e){
Log.d("TAG", "error");
}
}
});
OkHttp runs the onResponse method on the same background thread which it does the http call on. Because you're doing an async call this means it will not be the Android main thread.
To run code on the main thread from onResponse you can use a Handler and Runnable:
client.newCall(request).enqueue(new Callback() {
Handler handler = new Handler(SignUp.this.getMainLooper());
#Override
public void onFailure(Call call, IOException e) {
//...
}
#Override
public void onResponse(Call call, Response response) throws IOException {
handler.post(new Runnable() {
#Override
public void run() {
// whatever you want to do on the main thread
}
});
}

How to get Header from RxAndroid Response.?

This is the function which i used for the network calls.
private void generateNewCard()
{
showProgressDialog();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(NetworkCalls.BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
NetworkCalls.CustomerApi customerApi = retrofit.create(NetworkCalls.CustomerApi.class);
customerApi.addExistingCard(prefs.getString(Constants.AUTH_TOKEN, ""), "", CREATE_NEW_CARD)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<DataGeneral>() {
#Override
public void onCompleted() {
stopProgressDialog();
Log.d(TAG, "onCompleted DataGeneral" + DataGeneral.class);
}
#Override
public void onError(Throwable e) {
Log.d(TAG, "onError" + e.getMessage());
stopProgressDialog();
}
#Override
public void onNext(DataGeneral data) {
stopProgressDialog();
if (data.getStatus() == 1) {
}
}
});
}
and the interface class is here,
#FormUrlEncoded
#POST("add-loyalty-card")
Observable<DataGeneral> addExistingCard(#Field("Token") String token, #Field("cardHas") String cardHas, #Field("ltyCardId") String ltyCardId);
This works fine for me. I am getting desired result. I wish to know how can i get the Header from the response and is there a way to simplify the above code?
Any help would be really appreciated.

Categories

Resources