Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 841
Danation Avatar asked Jan 29 '13 01:01

Danation


2 Answers

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

like image 165
João Antunes Avatar answered Nov 01 '22 05:11

João Antunes


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

}
like image 29
Peter Ajtai Avatar answered Nov 01 '22 07:11

Peter Ajtai