Implémenter Google Analytics pour Firebase dans Android Webview

1. Introduction

Dernière mise à jour : 03/02/2022

8cef5cc6581b73d0.png

Points abordés

  • Créer une WebView très simple dans Android
  • Envoyer des événements WebView à Firebase

Prérequis

  • Projet Firebase avec le SDK Analytics implémenté
  • Android Studio version 4.2 ou ultérieure.
  • Un émulateur Android avec Android 5.0 ou version ultérieure.
  • Connaissances du langage de programmation Java.
  • Connaissances du langage de programmation JavaScript

2. Créer une WebView Web simple dans Android

Ajouter WebView dans la mise en page de l'activité

Pour ajouter une WebView à votre application dans la mise en page, ajoutez le code suivant au fichier XML de mise en page de votre activité :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".WebActivity"
>
  <WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
  />
</androidx.constraintlayout.widget.ConstraintLayout>;

Ajouter un WebView dans onCreate()

Pour charger une page Web dans la WebView, utilisez loadUrl(). La WebView doit être créée sur une activité noire. Par exemple, je vais l'implémenter dans la méthode onCreate :

public class WebActivity extends AppCompatActivity {
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        // Navigate to site
        myWebView.loadUrl("https://bittererhu.glitch.me");
 }
}

Toutefois, pour que cela fonctionne, votre application doit avoir accès à Internet. Pour accéder à Internet, demandez l'autorisation INTERNET dans votre fichier manifeste. Exemple :

<uses-permission android:name="android.permission.INTERNET" />

C'est tout ce dont vous avez besoin pour une WebView de base qui affiche une page Web.

Utiliser JavaScript dans les WebView

Si la page Web que vous prévoyez de charger dans votre WebView utilise JavaScript, vous devez activer JavaScript pour votre WebView. Une fois JavaScript activé, vous pouvez également créer des interfaces entre le code de votre application et votre code JavaScript.

JavaScript est désactivé par défaut dans une WebView. Vous pouvez l'activer via les WebSettings associés à votre WebView. Vous pouvez récupérer WebSettings avec getSettings(), puis activer JavaScript avec setJavaScriptEnabled().

Exemple :

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

Activité modifiée :

public class WebActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        WebView myWebView = (WebView) findViewById(R.id.webview);
        if(myWebView != null) {
            WebSettings webSettings = myWebView.getSettings();
            webSettings.setJavaScriptEnabled(true);
        }
        // Navigate to site
        myWebView.loadUrl("https://bittererhu.glitch.me");
  }
}

be627fcc51a6179f.png

3. Implémenter l'interface de pontage JavaScript

Gestionnaire JavaScript

La première étape pour utiliser Google Analytics dans une WebView consiste à créer des fonctions JavaScript pour transférer les événements et les propriétés utilisateur vers le code natif. L'exemple suivant montre comment procéder de manière compatible avec le code natif Android et Apple :

Dans cet exemple, j'ai créé un fichier JavaScript nommé script.js qui inclut les éléments suivants :

function logEvent(name, params) {
  if (!name) {
    return;
  }
  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.logEvent(name, JSON.stringify(params));
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'logEvent',
      name: name,
      parameters: params
    };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}


function setUserProperty(name, value) {
  if (!name || !value) {
    return;
  }

  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.setUserProperty(name, value);
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'setUserProperty',
      name: name,
      value: value
   };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}

Interface native

Pour appeler du code Android natif à partir de JavaScript, implémentez une classe avec des méthodes marquées @JavaScriptInterface : dans l'exemple ci-dessous, j'ai créé une classe Java appelée AnalyticsWebInterfcae.java :

public class AnalyticsWebInterface {

    public static final String TAG = "AnalyticsWebInterface";
    private FirebaseAnalytics mAnalytics;

    public AnalyticsWebInterface(Context context) {
        mAnalytics = FirebaseAnalytics.getInstance(context);
    }

    @JavascriptInterface
    public void logEvent(String name, String jsonParams) {
        LOGD("logEvent:" + name);
        mAnalytics.logEvent(name, bundleFromJson(jsonParams));
    }

    @JavascriptInterface
    public void setUserProperty(String name, String value) {
        LOGD("setUserProperty:" + name);
        mAnalytics.setUserProperty(name, value);
    }

    private void LOGD(String message) {
        // Only log on debug builds, for privacy
        if (BuildConfig.DEBUG) {
            Log.d(TAG, message);
        }
    }

    private Bundle bundleFromJson(String json) {
        // ...
    }
}

Once you have created the native interface, register it with your WebView so that it is visible to JavaScript code running in the WebView:

// Only add the JavaScriptInterface on API version JELLY_BEAN_MR1 and above, due to
// security concerns, see link below for more information:
// https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    mWebView.addJavascriptInterface(
            new AnalyticsWebInterface(this), AnalyticsWebInterface.TAG);
} else {
    Log.w(TAG, "Not adding JavaScriptInterface, API Version: " + Build.VERSION.SDK_INT);
}

Code final :

// [START analytics_web_interface]
public class AnalyticsWebInterface {

    public static final String TAG = "AnalyticsWebInterface";
    private FirebaseAnalytics mAnalytics;

    public AnalyticsWebInterface(Context context) {
        mAnalytics = FirebaseAnalytics.getInstance(context);
    }
    @JavascriptInterface
    public void logEvent(String name, String jsonParams) {
        LOGD("logEvent:" + name);
        mAnalytics.logEvent(name, bundleFromJson(jsonParams));
    }
    @JavascriptInterface
    public void setUserProperty(String name, String value) {
        LOGD("setUserProperty:" + name);
        mAnalytics.setUserProperty(name, value);
    }
    private void LOGD(String message) {
        // Only log on debug builds, for privacy
        if (BuildConfig.DEBUG) {
            Log.d(TAG, message);
        }
    }
    private Bundle bundleFromJson(String json) {
        // [START_EXCLUDE]
        if (TextUtils.isEmpty(json)) {
            return new Bundle();
        }

        Bundle result = new Bundle();
        try {
            JSONObject jsonObject = new JSONObject(json);
            Iterator<String> keys = jsonObject.keys();

            while (keys.hasNext()) {
                String key = keys.next();
                Object value = jsonObject.get(key);
                if (value instanceof String) {
                    result.putString(key, (String) value);
                } else if (value instanceof Integer) {
                    result.putInt(key, (Integer) value);
                } else if (value instanceof Double) {
                    result.putDouble(key, (Double) value);
                } else {
                    Log.w(TAG, "Value for key " + key + " not one of [String, Integer, Double]");
                }
            }
        } catch (JSONException e) {
            Log.w(TAG, "Failed to parse JSON, returning empty Bundle.", e);
            return new Bundle();
        }
        return result;
        // [END_EXCLUDE]
    }

Vous avez configuré l'interface JavaScript. Vous pouvez maintenant commencer à envoyer des événements analytiques.

4. Envoyer des événements via l'interface

Comme vous pouvez le voir, ma WebView est très simple. Elle comporte trois boutons, dont deux enregistrent un événement et l'autre enregistre une propriété utilisateur :

7a00ed1192151b19.png

Lorsque je clique sur les boutons, mon fichier "script.js" est appelé et le code suivant est exécuté :

document.getElementById("event1").addEventListener("click", function() {
    console.log("event1");
    logEvent("event1", { foo: "bar", baz: 123 });
});

document.getElementById("event2").addEventListener("click", function() {
  console.log("event2");
    logEvent("event2", { size: 123.456 });
});

document.getElementById("userprop").addEventListener("click", function() {
    console.log("userprop");
    setUserProperty("userprop", "custom_value");
});

Fichier script.js final :

/* If you're feeling fancy you can add interactivity 
    to your site with Javascript */

// prints "hi" in the browser's dev tools console
console.log("hi");

// [START log_event]
function logEvent(name, params) {
  if (!name) {
    return;
  }

  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.logEvent(name, JSON.stringify(params));
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'logEvent',
      name: name,
      parameters: params
    };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}
// [END log_event]

// [START set_user_property]
function setUserProperty(name, value) {
  if (!name || !value) {
    return;
  }

  if (window.AnalyticsWebInterface) {
    // Call Android interface
    window.AnalyticsWebInterface.setUserProperty(name, value);
  } else if (window.webkit
      && window.webkit.messageHandlers
      && window.webkit.messageHandlers.firebase) {
    // Call iOS interface
    var message = {
      command: 'setUserProperty',
      name: name,
      value: value
   };
    window.webkit.messageHandlers.firebase.postMessage(message);
  } else {
    // No Android or iOS interface found
    console.log("No native APIs found.");
  }
}
// [END set_user_property]

document.getElementById("event1").addEventListener("click", function() {
    console.log("event1");
    logEvent("event1", { foo: "bar", baz: 123 });
});

document.getElementById("event2").addEventListener("click", function() {
  console.log("event2");
    logEvent("event2", { size: 123.456 });
});

document.getElementById("userprop").addEventListener("click", function() {
    console.log("userprop");
    setUserProperty("userprop", "custom_value");
});

Il s'agit de la méthode de base pour envoyer des événements à Analytics.

5. Déboguer les événements WebView dans Firebase

Le débogage des événements WebView dans votre application fonctionne de la même manière que le débogage de n'importe quelle partie native de votre SDK :

Pour activer le mode Débogage, veuillez utiliser les commandes suivantes dans la console Android Studio :

adb shell setprop debug.firebase.analytics.app package_name

Une fois cette opération effectuée, vous pouvez tester et voir vos événements WebView prendre vie :

d230debf4ccfddad.png

6. Félicitations

Félicitations, vous avez créé une WebView dans votre application Android. Vous pouvez envoyer et mesurer les événements clés de votre entonnoir dans votre application qui se déroulent via des WebView. Pour en tirer le meilleur parti, nous vous suggérons également de l'associer à Google Ads et d'importer ces événements en tant que conversions.

Vous avez appris :

  • Envoyer des événements WebView à Firebase
  • Configurer et créer une WebView simple dans Android

Documents de référence