Implementando o Google Analytics para Firebase no Android Webview

Implementando o Google Analytics para Firebase no Android Webview

Sobre este codelab

subjectÚltimo fev. 8, 2022 atualizado
account_circleEscrito por Erhu Akpobaro

1. Introdução

Última atualização: 03/02/2022

8cef5cc6581b73d0.png

O que você aprenderá

  • Como criar um Webview bem simples no Android
  • Como enviar eventos Webview para o Firebase

O que você precisará

  • Projeto Firebase com SDK do Analytics implementado
  • Android Studio versão 4.2+.
  • Um emulador Android com Android 5.0+.
  • Familiaridade com a linguagem de programação Java.
  • Familiaridade com a linguagem de programação Javascript.

2. Crie um webview simples no Android

Adicionando Webview no layout da atividade

Para adicionar um WebView ao seu aplicativo no layout, adicione o seguinte código ao arquivo XML de layout da sua atividade:

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

Adicionando um WebView em onCreate()

Para carregar uma página da web no WebView, use loadUrl(). O Webview deve ser criado na atividade preta. Por exemplo, implementarei isso no método 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");
 
}
}

Antes que isso funcione, porém, seu aplicativo deve ter acesso à Internet. Para obter acesso à Internet, solicite permissão INTERNET em seu arquivo de manifesto. Por exemplo:

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

Isso é tudo que você precisa para um WebView básico que exiba uma página da web.

Usando Javascript em Webviews

se a página da web que você planeja carregar em seu WebView usar JavaScript, você deverá ativar o JavaScript para seu WebView. Depois que o JavaScript estiver ativado, você também poderá criar interfaces entre o código do seu aplicativo e o código JavaScript.

O JavaScript está desabilitado em um WebView por padrão. Você pode habilitá-lo através do WebSettings anexado ao seu WebView. Você pode recuperar WebSettings com getSettings() e, em seguida, ativar o JavaScript com setJavaScriptEnabled().

Por exemplo:

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

Atividade atualizada:

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. Implementando a interface Javascript em ponte

Manipulador Javascript

A primeira etapa para usar o Google Analytics em um WebView é criar funções JavaScript para encaminhar eventos e propriedades do usuário para o código nativo. O exemplo a seguir mostra como fazer isso de maneira compatível com o código nativo do Android e da Apple:

Neste exemplo, criei um arquivo Javascript chamado script.js que inclui o seguinte:

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 nativa

Para invocar o código Android nativo a partir de JavaScript, implemente uma classe com métodos marcados como @JavaScriptInterface : No exemplo abaixo criei uma nova classe Java chamada: 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);
}

Código 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]
   
}

Agora que você configurou a interface Javascript, está pronto para começar a enviar eventos analíticos.

4. Envio de eventos pela interface

Como você pode ver aqui meu Webview é muito simples, possui três botões, dois que registrarão um evento e outro que registrará uma propriedade do usuário:

7a00ed1192151b19.png

Assim que clicar nos botões, ele chamará meu arquivo "script.js" e executará o seguinte código:

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

Arquivo 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");
});

Esta é a maneira básica de enviar eventos para o Analytics

5. Depurar eventos do Webview no Firebase

A depuração de eventos do Webview no seu aplicativo funciona da mesma maneira que a depuração de qualquer parte nativa do seu SDK:

Para ativar o modo de depuração, use os seguintes comandos no console do Android Studio:

adb shell setprop debug.firebase.analytics.app package_name

Uma vez feito isso, você pode testar e ver seus eventos Webview ganharem vida:

d230debf4ccfddad.png

6. Parabéns

Parabéns, você criou com sucesso um webview em seu aplicativo Android. Você pode enviar e medir os principais eventos de funil em seu aplicativo que ocorrem por meio de webviews. Para aproveitar ao máximo, sugerimos também conectar-se ao Google Ads e importar esses eventos como conversões.

Você aprendeu

  • Como enviar eventos Webview para o Firebase
  • Como configurar e criar um Webview simples no Android

Documentos de referência