How can I replace OkHttpClient variable realized in custom Application class? - android

Dagger2 realization in App
Network component's module
#Provides
#Singleton
OkHttpClient provideOkHttpClient() {
return new OkHttpClient.Builder().addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Client-Id", Constants.CONFIG.APP_NAME)
.addHeader("RE-Phone-Number", phoneNumber)
.addHeader("RE-Access-Token", access_token);
Request request = builder.build();
return chain.proceed(request);
}
}).build();
}
It is called at the beginnig of app once. I need to change user credentials after their obtaining.
#Provides
#Singleton
Retrofit provideRetrofit(GsonConverterFactory gsonConverterFactory,
RxJavaCallAdapterFactory rxJavaCallAdapterFactory,
OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(gsonConverterFactory)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.build();
}
Api component's module
#Module
public class ApiModule {
#Provides
#PerFragment
CompanyService provideCompanyService(Retrofit retrofit){
return retrofit.create(CompanyService.class);
}
}

Related

OkHttp3 + Retrofit2 405 response

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.

Android + Retrofit2

I have a service, that return Single>
#GET("users/me/favourite-items-by-shop")
fun getFavourites(#Header("Authorization") authorization: String?):
Single<List<FavouriteItemResponse>>
And I have a repository where i want to get List
override fun getItems(): Single<List<ItemResponse>> {
return service.getFavourites(token)
.map(FavouriteItemResponse::items)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
But i get i mistake
required:Function<in List<FavouriteItemResponse>!, out (???..???)>!
Found: KProperty1<FavouriteItemResponse, ShopResponse>
How i can fix it?
Try this code to define header it wrong way..
#Headers("Content-Type:application/json")
#POST(NetworkConstants.WS_SEND_MESSAGE)
Call<MessageResponse> sendMessage(#Body UserData data);
and also you need to define token in all api request then add into retrofit object define time..
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 Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (context == null) {
request = request
.newBuilder()
.build();
} else {
request = request
.newBuilder()
.addHeader("Authorization", "Bearer " + AppSetting.getStringSharedPref(context, Constants.USER_KEY_TOKEN, ""))
.build();
}
return chain.proceed(request);
}
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
but this code in java
I can fix it that
return service.getFavourites(token)
.map { it[0] }
.map { it.items }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())

BaseUrl doesn't changed dynamically Dagger 2 & retrofit

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");
}

Android implementing HostSelectionInterceptor for dynamic change url using Dagger 2

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()

How to add multiple headers with ok Http

I am using Retrofit 2 and Okhttp for my android project. I want to add multiple headers in the api request.
This is my interceptor code :
public class NetworkInterceptors implements Interceptor {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Userid", "10034")
.addHeader("Securitykey", "Fb47Gi")
.build();
return chain.proceed(request);
}
}
This is not working properly. In server side I am getting only the last added header (in the above example I am getting only Securitykey missing "Userid" )
Please Help.
Thanks for support
I found the answer, This is working fine for me
public class NetworkInterceptors implements Interceptor {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Request newRequest;
newRequest = request.newBuilder()
.addHeader("Userid", "10034")
.addHeader("Securitykey", "Fb47Gi")
.build();
return chain.proceed(newRequest);
}
}
You can use this class pass the context in this class if user already logged in.
public class ApiClient {
public static final String BASE_URL = "";
private static Retrofit retrofit = null;
static Context mcontext;
public static Retrofit getClient(Context context,String baseUrl)
{
mcontext = context;
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(220, TimeUnit.SECONDS)// Set connection timeout
.readTimeout(220, TimeUnit.SECONDS)// Read timeout
.writeTimeout(220, TimeUnit.SECONDS)// Write timeout
.addInterceptor( HeaderInterceptor() )
// .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)// Add cache interceptor
// .cache(cache)// Add cache
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
private static Interceptor HeaderInterceptor() {
return new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.Request request = chain.request();
if(SharedPreference.getlogin(mcontext).equals("")){
request = request.newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer "+SharedPreference.gettoken(mcontext))
.build();
}
else {
request = request.newBuilder()
.addHeader("Accept", "application/json")
.build();
}
okhttp3.Response response = chain.proceed(request);
return response;
}
};
}
}

Categories

Resources