React Native & okhttp on Android - Set User-Agent

前端 未结 4 1029
梦如初夏
梦如初夏 2020-12-10 15:42

I\'m trying to set the User-Agent with React Native on Android. Did some research and it looks like I should use an okhttp Interceptor

相关标签:
4条回答
  • 2020-12-10 15:53

    Old issue, but we still ran into the same problem with React Native 0.59. This is what we did to fix (in Kotlin), as recent versions of okhttp prevent (and throw an exception) when trying to add an interceptor to an already initialized client:

    import android.os.Build
    import com.facebook.react.modules.network.OkHttpClientFactory
    import com.jaredrummler.android.device.DeviceName
    import okhttp3.Interceptor
    import okhttp3.OkHttpClient
    import okhttp3.Response
    
    class UserAgentInterceptor(val userAgent: String): Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val originalRequest = chain.request()
    
            val correctRequest = originalRequest.newBuilder()
                    .removeHeader("User-Agent")
                    .addHeader("User-Agent", userAgent)
                    .build()
            return chain.proceed(correctRequest)
        }
    }
    
    class UserAgentClientFactory(val appName: String, val appVersion: String, val buildNumber: String): OkHttpClientFactory {
        private fun userAgentValue(): String {
            val deviceName = DeviceName.getDeviceName()
            val osVersion = Build.VERSION.RELEASE
            return "$appName/$appVersion (build: $buildNumber; device: $deviceName; OS: Android $osVersion)"
        }
    
        override fun createNewNetworkModuleClient(): OkHttpClient {
            val builder = com.facebook.react.modules.network.OkHttpClientProvider.createClientBuilder()
            return builder.addInterceptor(UserAgentInterceptor(userAgent = userAgentValue())).build()
        }
    }
    

    This was done in a shared library between 2 apps, thus why we passed in the app name, version, and build number.

    Usage from the app itself looked like:

    private fun configureUserAgent() {
        val versionName = BuildConfig.VERSION_NAME
        val versionCode = BuildConfig.VERSION_CODE
        OkHttpClientProvider.setOkHttpClientFactory(UserAgentClientFactory(appName = "My App", appVersion = versionName, buildNumber = "$versionCode"))
    }
    

    This was called from the onCreate method in the main activity of the app.

    Hope this helps!

    0 讨论(0)
  • 2020-12-10 16:02

    So I've finally figured it out. Here is the solution for overriding the User-Agent of okhttp3 with React Native.

    Create a file called CustomInterceptor.java:

    package com.trevor;
    
    import okhttp3.Interceptor;
    import okhttp3.Request;
    import okhttp3.Response;
    
    import java.io.IOException;
    
    public class CustomInterceptor implements Interceptor {
    
        public CustomInterceptor() {}
    
        @Override
        public Response intercept(Interceptor.Chain chain) throws IOException {
            Request originalRequest = chain.request();
            Request requestWithUserAgent = originalRequest.newBuilder()
                .removeHeader("User-Agent")
                .addHeader("User-Agent", "Trevor")
                .build();
    
            return chain.proceed(requestWithUserAgent);
        }
    
    }
    

    Then in MainActivity.java override the onCreate method:

    ...
    import com.facebook.react.modules.network.OkHttpClientProvider;
    ...
    
    public class MainActivity extends ReactActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            attachInterceptor();
        }
    
        private void attachInterceptor() {
            OkHttpClient client = OkHttpClientProvider.getOkHttpClient();
            client.networkInterceptors().add(new CustomInterceptor());
        }
    }
    

    Note that I'm importing com.facebook.react.modules.network.OkHttpClientProvider; and overriding that client instead of creating a vanilla OkHttpClient since this is the one that React Native will use.

    0 讨论(0)
  • 2020-12-10 16:06

    React Native is iterating so quickly that the accepted answer didn't work for me.

    For RN 0.27.2 I had to import okhttp3.OkHttpClient in my CustomInterceptor and change the attachInterceptor() method in MainActivity to replace the client.

    private void attachInterceptor() {
        OkHttpClient currentClient = OkHttpClientProvider.getOkHttpClient();
        OkHttpClient replacementClient = currentClient.newBuilder().addNetworkInterceptor(new CustomInterceptor()).build();
        OkHttpClientProvider.replaceOkHttpClient(replacementClient);
    }
    

    Everything else from ekonstantinidis's answer works for me.

    0 讨论(0)
  • 2020-12-10 16:08

    I've implemented this functionality using OkHttp and my code is pretty the same as yours - and everything works fine.

    Consider using addHeader("User-Agent", "Trevor") instead of header("User-Agent", "Trevor"), because the latter will replace all of already set headers.

    I'm using okHttp.networkInterceptors().add(new CustomInterceptor()); instead of okHttp.interceptors().add(new CustomInterceptor());, but I don't think it's a matter of concern here.

    Update I do it in onCreate() method too. Everything works as it should.

    0 讨论(0)
提交回复
热议问题