8

I have an Android Phonegap/Cordova app that interacts with an ASP.NET MVC web application. I am trying to detect server side whether or not the web page is being loaded from a browser or from my Phonegap/Cordova app.

There are a few methods I have considered:

  1. Change the User Agent string. I found this stackoverflow link that describes a way to make that work. Unfortunately, it did not work for me. The request object did not have the custom user agent string.
  2. Include a custom header value. This can be done by modifying the cordova library (see this stackoverflow link.) Modifying libraries is usually a bad idea, though, since it becomes a maintenance problem in the future. (Update: this method didn't work after the first request.)
  3. Add something special to the query string when loading the first page. A cookie could then be set. This is kind of an ugly solution compared to a simple header change.

Am I doing something wrong on the user agent string change? Or is there another method that would accomplish this?

Community
  • 1
  • 1
Danation
  • 743
  • 8
  • 20

4 Answers4

5

So, for Cordova 5.1.1 and its platform version of Android 4.0.2 (What I got out of the box currently when using Cordova 5.1.1) these answers are no longer valid.

After some difficult poking around, the solution for the versions stated above is now the following:

In the usual MainActivity.java that is created by default by cordova and that extends CordovaActivity, override the makeWebViewEngine method:

@Override
    protected CordovaWebViewEngine makeWebViewEngine() {
        CordovaWebViewEngine cordovaWebViewEngine = super.makeWebViewEngine();
        WebSettings settings = ((SystemWebView) ((SystemWebViewEngine) cordovaWebViewEngine).getView()).getSettings();
        settings.setUserAgentString("MreaderMobile App / Android");
        return cordovaWebViewEngine;
    }

In the future, when they upgrade the version of the Android platform, this should be more easily done through the config.xml, but it's not an option ATM, as I commented on the bugfix thread CB-8960

Steve Lillis
  • 3,263
  • 5
  • 22
  • 41
João Antunes
  • 811
  • 9
  • 16
4

Looks like there's a pull request for something similar (add "cordova/phonegap" to UAS)
https://github.com/apache/cordova-android/pull/10

Here is the heart of it.

So I would extend DroidGap and override public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) :

...
WebSettings settings = this.appView.getSettings();
String userAgent = settings.getUserAgentString();
// can append or redefine here
userAgent += " PhoneGap/Cordova";
settings.setUserAgentString(userAgent);
...

Then you can use the extended DroidGap and have control over how you define the User Agent String.

Just confirmed this works, here is the full code using the current Cordova implementation:

package com.focusatwill.androidApp;

import org.apache.cordova.CordovaChromeClient;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaWebViewClient;
import org.apache.cordova.DroidGap;
import org.apache.cordova.api.LOG;

import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.widget.LinearLayout;


public class DroidGapCustom extends DroidGap {

    /**
     * Initialize web container with web view objects.
     *
     * @param webView
     * @param webViewClient
     * @param webChromeClient
     */
    public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) {
        LOG.d("EVENT", "Custom DroidGap.init()");

        // Set up web container
        this.appView = webView;

        // Custom addition of user agent string
        WebSettings settings = this.appView.getSettings();
        String userAgent = settings.getUserAgentString();
        // can append or redefine here
        userAgent += " PhoneGap/Cordova";
        settings.setUserAgentString(userAgent);

        this.appView.setId(100);

        this.appView.setWebViewClient(webViewClient);
        this.appView.setWebChromeClient(webChromeClient);
        webViewClient.setWebView(this.appView);
        webChromeClient.setWebView(this.appView);

        this.appView.setLayoutParams(new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT,
                1.0F));

        // Add web view but make it invisible while loading URL
        this.appView.setVisibility(View.INVISIBLE);
        this.root.addView(this.appView);
        setContentView(this.root);

        // Clear cancel flag
        this.cancelLoadUrl = false;
    }

}
Roland Tepp
  • 8,301
  • 11
  • 55
  • 73
Peter Ajtai
  • 56,972
  • 13
  • 121
  • 140
2

@Peter's answer gets there, but you don't need to override the entire init method. Here is an easier, more maintainable way:

    /***
     * This adds an actually useful user-agent string to the WebView.
     */
    @Override
    protected CordovaWebView makeWebView() {
        CordovaWebView wv = super.makeWebView();

        WebSettings settings = wv.getSettings();            
        String userAgent = settings.getUserAgentString();

        // can append or redefine here
        userAgent += " PhoneGap/Cordova Android";
        settings.setUserAgentString(userAgent);

        return wv;
    }
phreakhead
  • 14,721
  • 5
  • 39
  • 40
  • This method works and definitely seems more maintainable, however, I would like to point out that you must add `import android.webkit.WebSettings;` as it is not added by default by Cordova to CordovaApp.java. – ephbaum Feb 04 '15 at 16:26
1

If you're using a recent version of cordova, check this configuration guide on their site: http://cordova.apache.org/docs/en/dev/config_ref/index.html#Android%20Configuration

Search for UserAgent. There are 2 settings that allow you either to append something to the User-Agent (AppendUserAgent setting) or to override the User-Agent (OverrideUserAgent setting).

For example, in my android project, in the file res/xml/config.xml I've added the setting

<preference name="AppendUserAgent" value=" [this is from my hybrid app]" />

Upon applying this, my User-Agent is changed to something like:

Mozilla/5.0 (Linux; Android 5.0; SM-N9005 Build/LRX21V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 [this is from my hybrid app]
Victor Ionescu
  • 1,967
  • 2
  • 21
  • 24