Danation Danation - 5 months ago 202
Android Question

Custom user agent string or header without modifying cordova libs

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?

Answer

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

}