I'm trying to change the baseUrl of an android app dynamically but the url doesn't changed.
I'm taking the reference of David's answer from here,the OkHttp Approach Dagger + Retrofit dynamic URL and Set dynamic base url using Retrofit 2.0 and Dagger 2, but still no luck.
Initially the app point to the urls "https://imd.com/yeddydemo/wpApp/",which is our app base url.
After doing some googling i have written the following code to change the app base url points to https://imd.com/rahudemo/wpApp/ but it doesn't works correctly:
Can anyone please point out where i'm doing wrong.Thanks in Advance:)
Method to change the base url:
public void changeUrlConfiguration(String name){
NetComponent netComponent = DaggerNetComponent.builder()
.apiModule(new ApiModule("https://imd.com/rahudemo/wpApp/"))
.appModule(new AppModule((ImdPoApp)homeActivity.getApplication()))
.storageModule(new StorageModule((ImdPoApp)homeActivity.getApplication()))
.build();
ApiStories service = netComponent.retrofit().create(ApiStories.class);
HostSelectionInterceptor interceptor = netComponent.interceptor();
interceptor.setHost("https://imd.com/rahudemo/wpApp/","8WAtp8nUEOrzSu67t9tGITEo");
}
Interceptor class
public final class HostSelectionInterceptor implements Interceptor {
private volatile String host;
private String authKey;
public void setHost(String host,String authKey) {
this.host = host;
this.authKey=authKey;
new ApiModule(host);
}
#Override public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String host = this.host;
if (host != null) {
HttpUrl newUrl = HttpUrl.parse(host);
request = request.newBuilder()
.url(newUrl)
.build();
}
return chain.proceed(request);
}
}
ApiModule
#Module
public class ApiModule {
String mBaseUrl;
HostSelectionInterceptor sInterceptor;
public ApiModule(String mBaseUrl) {
this.mBaseUrl = mBaseUrl;
}
#Provides
#Singleton
Cache provideHttpCache(Application application) {/*..*/}
#Provides
#Singleton
Gson provideGson() {/*..*/}
#Provides
#Singleton
OkHttpClient provideOkhttpClient(Cache cache, HostSelectionInterceptor hostSelectionInterceptor) {
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.addInterceptor(chain -> {
Request request = chain.request();
Request.Builder builder = request.newBuilder().addHeader("Authkey", "8WAtp8nUEOrzSu67t9tGITEo");
return chain.proceed(builder.build());
});
client.addInterceptor(hostSelectionInterceptor);
client.cache(cache);
return client.build();
}
#Provides
#Singleton
HostSelectionInterceptor provideInterceptor() {
if (sInterceptor == null) {
sInterceptor = new HostSelectionInterceptor();
}
return sInterceptor;
}
#Provides
#Singleton
Retrofit provideRetrofit(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(mBaseUrl)
.client(okHttpClient)
.build();
}
}
In your method pass the base url want to change to newbaseurl
public void changeUrlConfiguration(String name, String newbaseurl){
NetComponent netComponent = DaggerNetComponent.builder()
.apiModule(new ApiModule(newbaseurl))
.appModule(new
AppModule((ImdPoApp)homeActivity.getApplication()))
.storageModule(new StorageModule((ImdPoApp)homeActivity.getApplication()))
.build();
ApiStories service = netComponent.retrofit().create(A
piStories.class);
HostSelectionInterceptor interceptor = netComponent.interceptor();
interceptor.setHost(newbaseurl,"8WAtp8nUEOrzSu67t9tGITEo");
}
By Changing my interceptor & ChangeUrlConfiguration method as below i can able to change the BaseUrl
Interceptor method
#Override public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String host = this.host;
if (host != null) {
HttpUrl newUrl = request.url().newBuilder()
.removePathSegment(0).removePathSegment(0).removePathSegment(0).addPathSegments(host).addPathSegment("wpApp").addEncodedPathSegment("api.php")
.build();
request = request.newBuilder()
.url(newUrl).addHeader("Authkey", "8WAtp8nU")
.build();
} else {
request = request.newBuilder().addHeader("Authkey", "8WAtp8nU")
.build();
}
try {
return chain.proceed(request);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
changeUrlConfiguration
public void changeUrlConfiguration(String constituencyName){
String newbaseurl="https://imdstar.com/rahuldemo/wpApp/";
hostSelectionInterceptor.setHost(newbaseurl,"8WAtp8nUEOrzSu67t9tGITEzIdgr6huIpXqo");
}
Related
In my Android app I'm using Retrofit + OkHttp to pass a client token in my post header in order to return an access token. I'm having trouble figuring out why I'm getting a 405 response. The 405 response shows my url is correct. This is my api service:
public interface TokenApiService {
String clientToken = "############";
#POST("token")
Call<Auth> fetchAuth(#Header("Authorization") String clientToken, #Body Auth auth);
}
This is my module. I'm able to return GET requests, but not POST:
#Module
#InstallIn(SingletonComponent.class)
public class NetworkModule {
public NetworkModule() {
}
#Provides
#Singleton
public static TokenApiService provideTokenApi(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(URL.ACCESS_TOKEN_URL)
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.callbackExecutor(Executors.newSingleThreadExecutor()).client(okHttpClient)
.build().create(TokenApiService.class);
}
#Provides
#Singleton
public static ClientApiService provideClientApi(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(URL.SCHEDULE_BASE_URL)
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.callbackExecutor(Executors.newSingleThreadExecutor()).client(okHttpClient)
.build().create(ClientApiService.class);
}
#Provides
#Singleton
public static ApiService provideApi(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(URL.BASE_URL)
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.callbackExecutor(Executors.newSingleThreadExecutor()).client(okHttpClient)
.build().create(ApiService.class);
}
#Provides
#Singleton
public static OkHttpClient provideClient(Interceptor interceptor) {
Cache cache = new Cache(new File(Application.getInstance().getCacheDir(), "http-cache"), 10 * 1024 * 1024);
return new OkHttpClient.Builder()
.addNetworkInterceptor(interceptor)
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.cache(cache)
.build();
}
#Provides
#Singleton
public static Interceptor provideInterceptor() {
return new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if (ConnectivityUtil.isNetworkConnected()) {
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(2, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.header("Cache-Control", cacheControl.toString())
.build();
} else {
Log.d("Paras", "Returning old");
return response;
}
}
};
}
}
Any help would be greatly appreciated.
I want to use two server url using retrofit, but only one is working when I am using two base url. Please tell me how to use two base url in android.
public class APIUtils {
public static String Url1 = "http://10.0.13.46:19460";
public static String Url12 = "http://freshcamera.herokuapp.com";
public static SOService getSOService(String url) {
return RetrofitClient.getClient(url1).create(SOService.class);
}
}
SOService class
public interface SOService {
//URL 2
#FormUrlEncoded
#POST("/api/user/LoginUser")
Call<Login> Login(#Field("username") String username, #Field("password")String password, #Field("grant_type")String passwords);
}
SOService_AI class
public interface SOService_AI {
//URL 1
#FormUrlEncoded
#POST("/finalresult1")
Call<List<AIImageProcessing>> AiImageCheck(#Field("img_data") String imgdata, #Field("name")String imgName);
}
I guess what you need is changing URL at runtime to a completely different one.
For example, the following code will override the URL passed as baseUrl to retrofit object.
#GET
public Call<ResponseBody> profilePicture(#Url String url);
Note: You can't add url param to #GET and #POST. The URL must be passed to #Url.
// ERROR ( #Url cannot be used with #GET URL)
#GET("users") // or POST
public Call<Foo> getUsers(#Url String url);
// CORRECT
#GET
public Call<Foo> getUsers(#Url String fullUrl);
Checkout this tutorial for further information.
if you are working two url then you create two retrofit object. because single retrofit object work on single url.
if you want to access two your make two retofit object like below code..
public class ApiClient {
private final static String BASE_URL = "https://simplifiedcoding.net/demos/";
private final static String BASE_URL2 = "http://freshcamera.herokuapp.com";
public static ApiClient apiClient;
private Retrofit retrofit = null;
private Retrofit retrofit2=null;
public static ApiClient getInstance() {
if (apiClient == null) {
apiClient = new ApiClient();
}
return apiClient;
}
//private static Retrofit storeRetrofit = null;
public Retrofit getClient() {
return getClient(null);
}
public Retrofit getClient2() {
return getClient2(null);
}
private Retrofit getClient(final Context context) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(60, TimeUnit.SECONDS);
client.writeTimeout(60, TimeUnit.SECONDS);
client.connectTimeout(60, TimeUnit.SECONDS);
client.addInterceptor(interceptor);
client.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
return chain.proceed(request);
}
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
private Retrofit getClient2(final Context context) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(60, TimeUnit.SECONDS);
client.writeTimeout(60, TimeUnit.SECONDS);
client.connectTimeout(60, TimeUnit.SECONDS);
client.addInterceptor(interceptor);
client.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
return chain.proceed(request);
}
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL2)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
}
then after access like below code ..
ApiClient.getInstance().getClient();
ApiClient.getInstance().getClient2();
with Kotlin its even easier
companion object {
// init Retrofit base server instance
val redditClient by lazy { ApiService.invoke(REDDIT_BASE_URL) }
val stackClient by lazy { ApiService.invoke(STACK_BASE_URL) }
private val loggingInterceptor = HttpLoggingInterceptor().apply {
this.level = HttpLoggingInterceptor.Level.BODY
}
operator fun invoke(baseUrl: String): ApiService {
val client = OkHttpClient.Builder().apply {
/**addNetworkInterceptor(StethoInterceptor()) */
addNetworkInterceptor(loggingInterceptor)
connectTimeout(10, TimeUnit.MINUTES)
readTimeout(10, TimeUnit.MINUTES)
writeTimeout(10, TimeUnit.MINUTES)
}.build()
return Retrofit.Builder()
.client(client)
.baseUrl(baseUrl)
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
just pass the baseUrl in the invoke method
This is really easy now
Simply use Post or Get without a constant url instead accept it in a parameter and annotate that parameter with #Url
#GET
suspend fun handshakeUser(#Url url : String): Response<JsonObject>
#POST
suspend fun makePostRequest(
#Header("Authorization") token: String = getToken(),
#Url url: String,
#Body inputModel: JsonObject
): Response<JsonObject>
I am trying to use an Interceptor to add a header when using Retrofit. I think I have created my Interceptor in the right way but I don't know what should I do to call it and connect it with my GET Retrofit method.
This is my Interceptor:
public class HeaderInterceptor
implements Interceptor {
#Override
public Response intercept(Chain chain)
throws IOException {
Request request = chain.request();
request = request.newBuilder()
.addHeader(Constants.VersionHeader.NAME, Constants.VersionHeader.VALUE)
.addHeader("Authorization", "Bearer " + token)
.addHeader("Origin","MY URL")
.build();
Response response = chain.proceed(request);
return response;
}
}
And this is my interface:
public interface CategoryService {
#GET("/v3/projects/{projectId}/categories/")
Call<ArrayList<Category2>> getProjectCategories(#Path("projectId") String projectId);
}
I also have this client which I don't know if I should use it anymore considering that I am using an Interceptor:
public class CategoryClient {
public static final String BASE_URL = "MY URL";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
So I have this GET method getProjectCategories, where I pass the projectID and it returns the contents. What I want to know is how can I call the method using the Interceptor and be able to get the results from the request.
I was able to fix my problem by creating a method called SendNetworkRequest sending the projectId as a parameter, and inside this class I created my OkHttpClient, my Interceptor and my retrofit builder to handle everything that i needed.
private void SendNetworkRequest(String projectID) {
OkHttpClient.Builder okhttpBuilder = new OkHttpClient.Builder();
okhttpBuilder.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder newRequest = request.newBuilder().header("Authorization", "Bearer " + token);
return chain.proceed(newRequest.build());
}
});
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("MY URL")
.client(okhttpBuilder.build())
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
CategoryService category = retrofit.create(CategoryService.class);
Call<ArrayList<Category2>> call = category.getProjectCategories(projectID, token);
call.enqueue(new Callback<ArrayList<Category2>>() {
#Override
public void onResponse(Call<ArrayList<Category2>> call, Response<ArrayList<Category2>> response) {
listCategories = response.body();
listCategories.remove(response.body().size() - 1);
if (response.body().size() > 0){
add_category_layout.setVisibility(View.VISIBLE);
layout_bar.setVisibility(View.VISIBLE);
message_body.setVisibility(View.INVISIBLE);
message_title.setVisibility(View.INVISIBLE);
edit_image.setVisibility(View.INVISIBLE);
adapter2 = new CategoryAdapter2(getApplicationContext(), listCategories);
recyclerView.setAdapter(adapter2);
recyclerView.setVisibility(View.VISIBLE);
}
}
#Override
public void onFailure(Call<ArrayList<Category2>> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
}
i just learn about how can i implementing Retrofit with Dagger2 to set dynamic change url on this reference
i try to make simple module with HostSelectionInterceptor class to use that on Dagger2, but i can't make that correctly and i get error:
my NetworkModule:
#Module(includes = ContextModule.class)
public class NetworkModule {
#Provides
#AlachiqApplicationScope
public HttpLoggingInterceptor loggingInterceptor() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
Timber.e(message);
}
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
return interceptor;
}
...
#Provides
#AlachiqApplicationScope
public HostSelectionInterceptor hostSelectionInterceptor() {
return new HostSelectionInterceptor();
}
#Provides
#AlachiqApplicationScope
public OkHttpClient okHttpClient(HostSelectionInterceptor hostInterceptor, HttpLoggingInterceptor loggingInterceptor, Cache cache) {
return new OkHttpClient.Builder()
.addInterceptor(hostInterceptor)
.addInterceptor(loggingInterceptor)
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.cache(cache)
.build();
}
}
and HostSelectionInterceptor module:
#Module(includes = {NetworkModule.class})
public final class HostSelectionInterceptor implements Interceptor {
private volatile String host;
#Provides
#AlachiqApplicationScope
public String setHost(String host) {
this.host = host;
return this.host;
}
public String getHost() {
return host;
}
#Provides
#AlachiqApplicationScope
#Override
public okhttp3.Response intercept(Chain chain) {
Request request = chain.request();
String host = getHost();
if (host != null) {
HttpUrl newUrl = request.url().newBuilder()
.host(host)
.build();
request = request.newBuilder()
.url(newUrl)
.build();
}
try {
return chain.proceed(request);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
i get this error now:
java.lang.IllegalArgumentException: unexpected host: http://myUrl.com/ at okhttp3.HttpUrl$Builder.host(HttpUrl.java:754)
problem is set host by setHost method on this line of code:
HttpUrl newUrl = request.url().newBuilder()
.host(host)
.build();
Based on this github comment, the solution is to replace
HttpUrl newUrl = request.url().newBuilder()
.host(host)
.build();
with
HttpUrl newUrl = HttpUrl.parse(host);
You should use interceptor like this:
class HostSelectionInterceptor: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
apiHost?.let { host ->
val request = chain.request()
val newUrl = request.url.newBuilder().host(host).build()
val newRequest = request.newBuilder().url(newUrl).build()
return chain.proceed(newRequest)
}
throw IOException("Unknown Server")
}
}
You just need to change at runtime the apiHost variable (var apiHost = "example.com"). Then add this interceptor to OkHttpClient builder:
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HostSelectionInterceptor())
.build()
I am trying to add basic authentication (username and password) to a Retrofit OkHttp client. This is the code I have so far:
private static Retrofit createMMSATService(String baseUrl, String user, String pass) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
I am using Retrofit 2.2 and this tutorial suggests using AuthenticationInterceptor, but this class is not available.
Where is the correct place to add the credentials? Do I have to add them to my interceptor, client or Retrofit object? And how do I do that?
Find the Solution
1.Write a Interceptor class
import java.io.IOException;
import okhttp3.Credentials;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class BasicAuthInterceptor implements Interceptor {
private String credentials;
public BasicAuthInterceptor(String user, String password) {
this.credentials = Credentials.basic(user, password);
}
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request authenticatedRequest = request.newBuilder()
.header("Authorization", credentials).build();
return chain.proceed(authenticatedRequest);
}
}
2.Finally, add the interceptor to an OkHttp client
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new BasicAuthInterceptor(username, password))
.build();
Retrofit 2
public class ServiceGenerator {
public static final String API_BASE_URL = "https://your.api-base.url";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(
Class<S> serviceClass, String username, String password) {
if (!TextUtils.isEmpty(username)
&& !TextUtils.isEmpty(password)) {
String authToken = Credentials.basic(username, password);
return createService(serviceClass, authToken);
}
return createService(serviceClass, null);
}
public static <S> S createService(
Class<S> serviceClass, final String authToken) {
if (!TextUtils.isEmpty(authToken)) {
AuthenticationInterceptor interceptor =
new AuthenticationInterceptor(authToken);
if (!httpClient.interceptors().contains(interceptor)) {
httpClient.addInterceptor(interceptor);
builder.client(httpClient.build());
retrofit = builder.build();
}
}
return retrofit.create(serviceClass);
}
}
Retrofit 1.9
public class ServiceGenerator {
public static final String API_BASE_URL = "https://your.api-base.url";
private static RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(API_BASE_URL)
.setClient(new OkClient(new OkHttpClient()));
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(Class<S> serviceClass, String username, String password) {
if (username != null && password != null) {
// concatenate username and password with colon for authentication
String credentials = username + ":" + password;
// create Base64 encodet string
final String basic =
"Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addHeader("Authorization", basic);
request.addHeader("Accept", "application/json");
}
});
}
RestAdapter adapter = builder.build();
return adapter.create(serviceClass);
}
}
AuthenticationInterceptor.java
public class AuthenticationInterceptor implements Interceptor {
private String authToken;
public AuthenticationInterceptor(String token) {
this.authToken = token;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.header("Authorization", authToken);
Request request = builder.build();
return chain.proceed(request);
}
}
Usage
Retrofit 2
Interface
public interface LoginService {
#POST("/login")
Call<User> basicLogin();
}
Requester
LoginService loginService =
ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
Call<User> call = loginService.basicLogin();
call.enqueue(new Callback<User >() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
// user object available
} else {
// error response, no access to resource?
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
// something went completely south (like no internet connection)
Log.d("Error", t.getMessage());
}
}
Retrofit 1.9
Interface
public interface LoginService {
#POST("/login")
void basicLogin(Callback<User> cb);
}
Requester
LoginService loginService =
ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
loginService.basicLogin(new Callback<User>() {
#Override
public void success(User user, Response response) {
// user object available
}
#Override
public void failure(RetrofitError error) {
// handle errors, too
}
});
More information see here.
add header interceptor
public class HeaderInterceptor implements Interceptor {
private PreferencesRepository mPrefs;
private String mAuth;
public HeaderInterceptor(PreferencesRepository p) {
mPrefs = p;
}
#Override
public Response intercept(Chain chain) throws IOException {
mAuth = (mPrefs.getAuthToken() != null)?mPrefs.getAuthToken():"";
Request r = chain.request()
.newBuilder()
.addHeader("Accept", "application/json")
// authorization token here
.addHeader("Authorization", "Bearer" + mAuth)
.build();
return chain.proceed(r);
}
}
add cacheinterceptor (optional)
public class CacheInterceptor implements Interceptor {
Context mContext;
public CacheInterceptor(Context context) {
this.mContext = context;
}
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (request.method().equals("GET")) {
if (DeviceUtils.isConnected(mContext)) {
request = request.newBuilder()
.header(Constant.CACHE_CONTROL, "only-if-cached")
.build();
} else {
request = request.newBuilder()
.header(Constant.CACHE_CONTROL, "public, max-stale=2419200")
.build();
}
}
Response originalResponse = chain.proceed(request);
return originalResponse.newBuilder()
.header(Constant.CACHE_CONTROL, "max-age=600")
.build();
}
}
implement it
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(HttpLoggingInterceptor.Level.BODY);
long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(new File(mContext.getCacheDir(), "http"), SIZE_OF_CACHE);
new OkHttpClient.Builder()
.addInterceptor(logger)
.addInterceptor(new HeaderInterceptor(u))
.cache(cache)
.addNetworkInterceptor(new CacheInterceptor(mContext))
.connectTimeout(Constant.CONNECTTIMEOUT, TimeUnit.SECONDS)
.readTimeout(Constant.READTIMEOUT, TimeUnit.SECONDS)
.writeTimeout(Constant.WRITETIMEOUT, TimeUnit.SECONDS)
.build();
Of course using auth interceptor is correct way (as explained in other answers). Although, if you need basic authentication only for single call, then auth header can be added directly in Retrofit request:
import okhttp3.Credentials
// Create credentials
val login = "some login"
val password = "some password"
// Below code will create correct Base64 encoded Basic Auth credentials
val credentials = Credentials.basic(login, password)
// Then in your Retrofit API interface
interface MyApi {
#POST("get_user")
fun getUser(#Header("Authorization") credentials: String): ResponseBody
}