11

I am building an Android app to display content feed from a server. The server is a mobile website (like http://m.google.com) which tracks the traffic from various mobile clients. To differentiate an Android client, how do I provide a generic string for my app?

Here's why I ask that:

Some of the Android devices I got have UA strings like:

Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; ADR6400L 4G Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1

Mozilla/5.0 (Linux; U; Android 2.1; en-us; Eclair_SPR Build/30201) AppleWebKit/520.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/520.17

I need to append a string to the UserAgent string to identify my app. For eg:

I need to do something like this: Mozilla/5.0 (Linux; U; Android 2.1; en-us; Eclair_SPR Build/30201) AppleWebKit/520.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/520.17 Android_MyFirstApp.

Is this the correct way to do it?

davioooh
  • 23,742
  • 39
  • 159
  • 250
Sagar Hatekar
  • 8,700
  • 14
  • 56
  • 72

5 Answers5

11

To change the user agent you need to send a custom User-Agent: header with your HTTP request. Assuming you're using the Android org.apache.http.client.HttpClient class, you have two options:

  1. Set the user agent header on each request. You do this by calling setHeader() on your HttpRequest (HttpPost, HttpGet, whatever) object after you create it:
HttpGet get = new HttpGet(url);
get.setHeader("User-Agent", myUserAgent);
  1. Change the default User Agent parameter, which will affect all future instances of that HttpClient class. You do this by reading the HttpParams collection from your client with getParams() then updating the user agent using setParameter():
DefaultHttpClient http = new DefaultHttpClient(); 
http.getParams().setParameter(CoreProtocolPNames.USER_AGENT, myUserAgent);

If you want to append instead of replace the user agent, you can read the existing one first, change it, and set it back using either of the above methods.

EDIT:

Since you said you're using the WebView view you will need to use the WebSettings customization point there. It's basically the same process. Before you call whichever load() method (loadUrl, loadData, etc) you do set the user agent. The changed user-agent will persist as long as that instance of the WebView is around, so you'd do this in the onCreate() of your Activity:

view = (WebView)findViewById(R.id.webview);
view.getSettings().setUserAgentString(myUserAgent);

Again, if you want to append instead of replace, use getUserAgentString() to read it, then update it and set it back again.

davioooh
  • 23,742
  • 39
  • 159
  • 250
Michael Edenfield
  • 28,070
  • 4
  • 86
  • 117
1

When you use the web view to access the user-agent, make sure you run the

new WebView(this).getSettings().getUserAgentString();

on the UI thread.

If you want to access the user agent in the background thread. use

System.getProperty("http.agent")

To check whether a user-agent is valid or not use this https://deviceatlas.com/device-data/user-agent-tester

1

Since you control your Android client, why don't you create a generic header string, and set it in header every time your app makes a server call? That way you can ensure the string is unique, and can also add any other useful info to be sent to server. You should be able to use webView.loadUrl() to set extra headers.

omermuhammed
  • 7,365
  • 4
  • 27
  • 40
1

You can totally do that and at developer.android.com suggest it as well, when they talk about the WebView, especially if you want to build a web app for your web view. Reference here: http://developer.android.com/guide/webapps/webview.html

Id suggest not only to keep reference to the application in your User Agent but to also keep track of the version as well.

Anyways, I was looking to change my UA too and the discussions here and the encouraged me to do so as well.

Here is my implementation:

On your Android APP:

String versionName="";
int versionCode=0;
try {
    versionName = getBaseContext().getPackageManager().getPackageInfo(getBaseContext().getPackageName(), 0 ).versionName;
    versionCode = getBaseContext().getPackageManager().getPackageInfo(getBaseContext().getPackageName(), 0 ).versionCode;
} catch (NameNotFoundException e) {
    e.printStackTrace();
}

If you want to auto increment the build number aka. versionCode you may take a look to this other Stack Overflow post as well, the C# solution.

Afterwards you just change the User Agent.

WebView mywebview = (WebView)findViewById(R.id.webView);
String myUserAgent = " MyFancyAPPName  V."+versionName+"."+versionCode;

mywebview.getSettings().setUserAgentString(mywebview.getSettings().getUserAgentString()+myUserAgent);

On your Web Application: In PHP

<?php
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);

if(stripos($ua,'MyFancyAPPName') !== false){
    //do whatever you wish here
}
?>

Or In JavaScript

var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf("MyFancyAPPName") > -1;
if(isAndroid) { 
    //do whatever you wish here
}

Or you can directly detect it from the .htaccess file:

RewriteCond %{HTTP_USER_AGENT} ^.*MyFancyAPPName.*$
RewriteRule ^(.*)$ http://www.MyWebSite/MyFancyAPPName [R=301]
Community
  • 1
  • 1
jkanini
  • 376
  • 4
  • 8
0

It depends on what framework you're using to make your requests. If you're using the org.apache classes, you can call setHeader('User-Agent', "Generic user agent here") on the HttpMessage you use to do your request.

Jason LeBrun
  • 13,037
  • 3
  • 46
  • 42
  • thanks for the info. Actually, I don't do a Http request. I have a WebView in which I render the HTML content so I just do webView.loadURL() So, all I can do is webView.getSettings().setUserAgentString() Any insight? – Sagar Hatekar Apr 14 '11 at 20:18
  • You have the answer there... why isn't setUserAgentString() working for you? Get the current value with getUserAgentString() and then append your value. Have you tried this and found that it doesn't work? – Jason LeBrun Apr 14 '11 at 20:34
  • Thanks for the helpful info. yes, I tried the same approach that you suggested but i was wondering if that's the correct way to do. Since, the myappname string will be an alien string to the browser and it shouldn't result in undefined behaviour. Nevertheless, it works fine! Thanks! – Sagar Hatekar Apr 14 '11 at 22:12
  • you could post your above comment as an answer so I can upvote it. Thanks! – Sagar Hatekar Apr 14 '11 at 22:13