61

I am using okhttp 2.0 in my Android app and didn't find a way to set some common User Agent for all outgoing requests.

I thought I could do something like

OkHttpClient client = new OkHttpClient();
client.setDefaultUserAgent(...)

...but there's no such method or similar. Of course I could provide some extension utility method which would wrap a RequestBuilder to attach .header("UserAgent") and then I would use it for building all my requests, but I thought maybe I missed some existing and simpler way?

dimsuz
  • 8,969
  • 8
  • 54
  • 88

7 Answers7

108

You can use an interceptor to add the User-Agent header to all your requests.

For more information about okHttp interceptors see http://square.github.io/okhttp/interceptors/

Example implementation of this interceptor:

/* This interceptor adds a custom User-Agent. */
public class UserAgentInterceptor implements Interceptor {

    private final String userAgent;

    public UserAgentInterceptor(String userAgent) {
        this.userAgent = userAgent;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request requestWithUserAgent = originalRequest.newBuilder()
            .header("User-Agent", userAgent)
            .build();
        return chain.proceed(requestWithUserAgent);
    }
}

Test for the UserAgentInterceptor:

public void testUserAgentIsSetInRequestHeader() throws Exception {

    MockWebServer server = new MockWebServer();
    server.enqueue(new MockResponse().setBody("OK"));
    server.play();
    String url = server.getUrl("/").toString();

    OkHttpClient client = new OkHttpClient();
    client.networkInterceptors().add(new UserAgentInterceptor("foo/bar"));
    Request testRequest = new Request.Builder().url(url).build()
    String result = client.newCall(testRequest).execute().body().string();
    assertEquals("OK", result);

    RecordedRequest request = server.takeRequest();
    assertEquals("foo/bar", request.getHeader("User-Agent"));
}
hd1
  • 33,938
  • 5
  • 80
  • 91
josketres
  • 3,329
  • 1
  • 26
  • 23
35

In case anyone is looking for this working with OkHttp 3 and in Kotlin:

val client = OkHttpClient.Builder()
    .addNetworkInterceptor { chain ->
      chain.proceed(
          chain.request()
              .newBuilder()
              .header("User-Agent", "COOL APP 9000")
              .build()
      )
    }
    .build()
willcwf
  • 712
  • 7
  • 10
10

OkHttp v2.1 which is set to be released in the next few weeks will automatically set a User-Agent header if one is not already set.

As of now there isn't a good way to add this header to every request in a centralized way. The only workaround is to include the header manually for every Request that is created.

Jake Wharton
  • 75,598
  • 23
  • 223
  • 230
10

Based on @josketres answer, here is a similar Interceptor for OkHttp version 3

public class UserAgentInterceptor implements Interceptor {
    private final String mUserAgent;

    public UserAgentInterceptor(String userAgent) {
        mUserAgent = userAgent;
    }

    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request request = chain.request()
                .newBuilder()
                .header("User-Agent", mUserAgent)
                .build();
        return chain.proceed(request);
    }
}

Plus the updated test:

@Test
public void testUserAgentIsSetInRequestHeader() throws IOException, InterruptedException {
    final String expectedUserAgent = "foo/bar";

    MockWebServer server = new MockWebServer();
    server.enqueue(new MockResponse().setBody("OK"));
    server.start();

    OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
    okHttpBuilder.addInterceptor(new UserAgentInterceptor(expectedUserAgent));
    Request request = new Request.Builder().url(server.url("/").url()).build();
    ResponseBody result = okHttpBuilder.build().newCall(request).execute().body();
    assertNotNull(result);
    assertEquals("OK", result.string());

    assertEquals(expectedUserAgent, server.takeRequest().getHeader("User-Agent"));
}
friederbluemle
  • 33,549
  • 14
  • 108
  • 109
7

You have to use builder in newer versions. (Sep 2021)

    client = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @NotNull
                @Override
                public Response intercept(@NotNull Chain chain) throws IOException {
                    Request originalRequest = chain.request();
                    Request requestWithUserAgent = originalRequest.newBuilder()
                            .header("User-Agent", "My Agent is so cool")
                            .build();
                    return chain.proceed(requestWithUserAgent);
                }
            })
            .build();
ucMedia
  • 4,105
  • 4
  • 38
  • 46
6

Using an intercepter is no longer required in the newer versions of OkHttp. Adding a user agent is as simple as:

Request request = new Request.Builder()
    .url("http://www.publicobject.com/helloworld.txt")
    .header("User-Agent", "OkHttp Example")
    .build();

Source: OkHttp wiki.

Saket
  • 2,945
  • 1
  • 29
  • 31
  • 5
    But that would require you do it for every request you send. An accepted answer has the same code you provided, only run inside an interceptor which is a nicer solution for the case where all the requests must have a certain User Agent. – dimsuz Mar 27 '17 at 22:30
  • 1
    Yes, this is useful only if you have a fixed header. – Saket Mar 28 '17 at 11:37
0

Adding an interceptor with Kotlin,

private val client = OkHttpClient.Builder()
   .addInterceptor(object: Interceptor{
       override fun intercept(chain: Interceptor.Chain): Response {
           val request = chain.request()
           val reqBuilder = request.newBuilder()
               .header("Accept-Language", Locale.getDefault().language)
               .header("User-Agent", "New User-Agent String")
           return chain.proceed(reqBuilder.build())
       }
   })
  .build()

private val retrofit: Retrofit = Retrofit.Builder()
   .baseUrl(Constants.BASE_URL)
   .client(client)
   .addConverterFactory(GsonConverterFactory.create())
   .build()
All Іѕ Vаиітy
  • 24,861
  • 16
  • 87
  • 111