Probably a novice question but I'm wondering where I actually catch the logs in log cat. Is there a particular place I put a log, a special regex to use etc. This is what my interceptor looks like:
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okClient = new OkHttpClient.Builder().addInterceptor(interceptor).build();
// Retrofit setup
Retrofit client = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okClient)
.build();
And here is an api call where the body is null
retrofit2.Call<GeneralTokenResponse> generalTokenResponseCall = ApiInterface.getGeneralAccessToken(ApiGeneral.API_VERSION);
generalTokenResponseCall.enqueue(new retrofit2.Callback<GeneralTokenResponse>() {
#Override
public void onResponse(retrofit2.Call<GeneralTokenResponse> call, retrofit2.Response<GeneralTokenResponse> response) {
Log.d("DEBUG", "body: "+response.body());
}
#Override
public void onFailure(retrofit2.Call<GeneralTokenResponse> call, Throwable t) {
}
});
I use so:
// init okhttp 3 logger
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override public void log(String message) {
Log.d("MyTAG", "OkHttp: " + message);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
Related
I am trying to make an app that will list all github repos public/private of a user via github REST API.
Here is GithubService for retrofit.
public interface GithubService {
#GET("user")
Call<User> getUser(#Header("Authorization") String authHeader);
#GET("users/{user}/repos")
Call<List<GitHubRepo>> userRepos(#Header("Authorization") String authHeader, #Path("user") String userId);}
I have a login form which takes in username and user's personal access token as password and here is the code that I use for requesting user info, this returns valid user info:
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.client(clientBuilder.build())
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
GithubService service = retrofit.create(GithubService.class);
String cred = Credentials.basic(username, password);
service.getUser(cred).enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
Log.d(TAG, "onResponse: " + response.isSuccessful());
fetchRepos(password, response.body());
}
#Override
public void onFailure(Call<User> call, Throwable t) {
Log.d(TAG, "onFailure: " + t.getMessage());
}
});
in fetchRepos I am trying to use the personal access token as auth header for requesting user repos but it returns null, here is the code:
private void fetchRepos(String pat, User user) {
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.client(clientBuilder.build())
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
GithubService service = retrofit.create(GithubService.class);
service.userRepos(pat, user.getLogin()).enqueue(new Callback<List<GitHubRepo>>() {
#Override
public void onResponse(Call<List<GitHubRepo>> call, Response<List<GitHubRepo>> response) {
Log.d(TAG, "onResponse: " + response.isSuccessful());
}
#Override
public void onFailure(Call<List<GitHubRepo>> call, Throwable t) {
}
});
}
Where am I wrong here? How to continue with authorization to request user repos and how is Two-Factor code integrated into authorization?
Github OAuth V3 required Web-based Authentication, You can try this SDK, It will reduce your boilerplate code and returns proper Auth Token for Github. And it's lightweight, no extra packages required.
SDK Link: https://github.com/debojyoti452/GithubLoginSDK
Hello Guys I am trying to realtime get data when change data in API automatic referesh my layout and updated data show it. How can i do that?
Here is my Code :-
I use this Dependencies :-
// retrofit, gson
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:retrofit:2.6.1'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
Here is my API interface method :-
#GET("get_doctor_expense_categories.php")
Call<GetExpenseCategoriesListResponse> get_doctor_expense_categories(#Query("doctor_id") String doctor_id);
And this my ApiClient :-
public class ApiClient {
private static final String ROOT_URL = "YOUR URL";
public static ApiInterface getApiService() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build();
Gson gson = new GsonBuilder().setLenient().create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ROOT_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
return retrofit.create(ApiInterface.class);
}
}
And This is my API call Method Where i get Data into List :-
private void getCategories(String doctor_id) {
progressDialog = CustomProgressBar.createProgressDialog(ViewCategoriesActivity.this);
final ApiInterface api = ApiClient.getApiService();
Call<GetExpenseCategoriesListResponse> call = api.get_doctor_expense_categories(doctor_id);
call.enqueue(new Callback<GetExpenseCategoriesListResponse>() {
#SuppressLint("SetTextI18n")
#Override
public void onResponse(#NonNull Call<GetExpenseCategoriesListResponse> call, #NonNull Response<GetExpenseCategoriesListResponse> response) {
if (response.code() == 200) {
progressDialog.dismiss();
if (response.body() != null) {
if (response.body().getStatus().equalsIgnoreCase("success")) {
expanseCatList = response.body().getData();
if (expanseCatList.isEmpty()) {
txt_no_data_found.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
txt_no_data_found.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
expanseCatListAdapter = new CategoriesListAdapter(expanseCatList, ViewCategoriesActivity.this, ViewCategoriesActivity.this::catClick);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(ViewCategoriesActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(expanseCatListAdapter);
}
} else {
Toast.makeText(ViewCategoriesActivity.this, "" + response.body().getMessage(), Toast.LENGTH_SHORT).show();
}
}
} else if (response.code() == 400) {
progressDialog.dismiss();
Toast.makeText(ViewCategoriesActivity.this, "Bad Request", Toast.LENGTH_SHORT).show();
} else if (response.code() == 401) {
progressDialog.dismiss();
Toast.makeText(ViewCategoriesActivity.this, "Unauthorized User", Toast.LENGTH_SHORT).show();
} else if (response.code() == 404) {
progressDialog.dismiss();
Toast.makeText(ViewCategoriesActivity.this, "Not Found", Toast.LENGTH_SHORT).show();
} else if (response.code() == 500) {
progressDialog.dismiss();
Toast.makeText(ViewCategoriesActivity.this, "Internal Server Error", Toast.LENGTH_SHORT).show();
} else {
progressDialog.dismiss();
Toast.makeText(ViewCategoriesActivity.this, "Unknown Error", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<GetExpenseCategoriesListResponse> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(ViewCategoriesActivity.this, "onFailer: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
This is not possible using retrofit if you want real time data you can use soup/socket
This is my retrofit setup.
public interface ApiInterface {
#GET("place/autocomplete/json?")
Call<ResponseBody> doPlaces(#QueryMap Map<String, String> options);}
public class RetrofitClient {
public static final String BASE_URL = Environment.getBaseUrl();
public static ApiInterface service (Context context) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(3, TimeUnit.MINUTES)
.readTimeout(3, TimeUnit.MINUTES)
.writeTimeout(3, TimeUnit.MINUTES)
.addInterceptor(logging)
.addInterceptor(new NetworkConnection(context))
.addInterceptor(new ResponseStatus(context))
.build();
ApiInterface service = new Retrofit.Builder()
.baseUrl(BASE_URL).client(okHttpClient)
.build().create(UrlServices.class);
return service;
}
public static void getContentData(final Dialog dialog, final Call<ResponseBody> method, final WebResponse webResponse) {
if (dialog != null)
AppProgressDialog.show(dialog);
method.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (dialog != null)
AppProgressDialog.hide(dialog);
JsonUtil.handleResponse(response, webResponse);
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable throwable) {
if (dialog != null)
AppProgressDialog.hide(dialog);
webResponse.onResponseFailed(throwable.getMessage());
}
});
}
}
public interface WebResponse {
void onResponseSuccess(Response<ResponseBody> result);
void onResponseFailed(String error);
}
Use in Activity/Fragment
RetrofitClient.getContentData(new Dialog(context), RetrofitClient.service(context).doPlaces(hashMap), new WebResponse() {
#Override
public void onResponseSuccess(Response<ResponseBody> result) {
}
#Override
public void onResponseFailed(String error) {
}
});
In my application, I connect to a server and have to get a successful response to my further working, after such type of response, in general, I get two tokens ( access+refresh). For my further actions, I have to use my access token because I won't be able to get data. This token, in general, expires in 30 minutes. I can't understand how I can get a new token from the server without fails of my application. I had seen some questions and this Refreshing OAuth token using Retrofit without modifying all calls one was the best I think. But I can't understand the way of using it for me.
Right now I am using such an interface:
public interface APIService {
#Headers("Content-type: application/json")
#POST("/v1/login")
Call<Post> auth(#Body Post body);
#Headers({"Content-type: application/json",
"Authorization: Bearer access_token"})
#GET("/v1/message/list")
Call<Message> getInMess(#Query("type") int type, #Query("offset") int offset);
}
there I have to insert my access token by hands.
And then in my MainActivity Class I initialize my interface:
public void sendPost()
{
final EditText titleEt = findViewById(R.id.login);
final EditText bodyEt = findViewById(R.id.password);
final String a = titleEt.getText().toString().trim();
final String b = bodyEt.getText().toString().trim();
saveData();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://server/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService mAPIService = retrofit.create(APIService.class);
//retrofit.create(APIService.class);
mAPIService.auth(new Post(a, b)).enqueue(new Callback<Post>() {
#Override
public void onResponse(#NonNull Call<Post> call, #NonNull Response<Post> response) {
if (response.isSuccessful()) {
Toast.makeText(LoginActivity.this, "Post submitted to API.", Toast.LENGTH_LONG).show();
Intent intent = new Intent(LoginActivity.this, SecondScreen.class);
findViewById(R.id.btn_submit).getBackground().setColorFilter(Color.parseColor("#1cd000"), PorterDuff.Mode.MULTIPLY);
startActivity(intent);
} else {
Toast.makeText(LoginActivity.this, "Unable to submit post to API.Error!!!", Toast.LENGTH_LONG).show();
findViewById(R.id.btn_submit).getBackground().setColorFilter(Color.parseColor("#FF0000"), PorterDuff.Mode.MULTIPLY);
}
}
#Override
public void onFailure(#NonNull Call<Post> call, #NonNull Throwable t) {
Toast.makeText(LoginActivity.this, "Unable to submit post to API.", Toast.LENGTH_LONG).show();
}
});
}
Please help me to understand the strategy of my further development because I can't solve my problem.
P.S. Sorry for my bad English))
You need to intercept the request and add the header in your interceptor. I use this in my applications :
public class AuthenticationInterceptor implements Interceptor {
public AuthenticationInterceptor(Context context) {
}
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if(!YOUR_TOKEN.isEmpty()) {
Request authenticatedRequest = request.newBuilder().header("Authorization", "Bearer:" + YOUR_TOKEN).build();
return chain.proceed(authenticatedRequest);
}
return chain.proceed(request);
}
}
I'm using Retrofit 2.0, the code below will log:
"insertListingImages, SocketOutOfTimeException:TimeOut timeout".
Why is it causing a timeout exception? how do I resolve it? The odd thing is that if the retrofit call, hi() isn't inside the retrofit call, insertListingImages() everything would work fine.
retrofit = new Retrofit.Builder()
.baseUrl("http://IP_ADRESS/")
.addConverterFactory(GsonConverterFactory.create())
.build().create(DatabaseInterface.class);
retrofit.insertListingImages(imageListingRequest).enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Void> call, Response<Void> response) {
Log.d("insertListingImages", "Success");
retrofit.hi().enqueue(new Callback<Void>(){
#Override
public void onResponse(Call<Void> call, Response<Void> response){
Log.d("hiTest", "Success");
}
#Override
public void onFailure(Call<Void> call, Throwable t) {
Log.d("hiTest", "fail: " + t.toString() + " " + t.getMessage());
}
});
}
#Override
public void onFailure(Call<Void> call, Throwable t) {
Log.d("insertListingImages", "fail: " + t.toString() + " " + t.getMessage());
}
});
You can change the connection time out and read timeout by this code. you have to set the custom client for the retrofit
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(120, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS).addInterceptor(interceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.url)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Here in the above code set the time out as 120 sec, you can change that according to your need
Needed to add below line in the build.gradle file
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
I am using retrofit for parsing JSON from Api. When i am using mobile network (Not WIFI) then continuously making query to retrieve response from api sometimes getting time out error.
Code :
userLogin("Username").
enqueue(new RetrofitCallback<PatientModel>() {
#Override
public void onSuccess(PatientModel result) {
if (null != result) {
loginResponse(result);
}
}
#Override
public void onFailure(int code, String msg) {
}
#Override
public void onThrowable(Throwable t) {
}
#Override
public void onFinish() {
hideProgress();
}
});
Maybe you must increase time out. Could you try this :
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.create();
okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL).client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
apiService = retrofit.create(IService.class);