1. Introdução
Última atualização:03/02/2022
O que você aprenderá
- Como criar uma WebView muito simples no Android
- Como enviar eventos da WebView para o Firebase
O que é necessário
- Projeto do Firebase com o SDK do Google Analytics implementado
- Android Studio versão 4.2 ou mais recente.
- Um Android Emulator com Android 5.0 ou mais recente.
- Noções básicas da linguagem de programação Java.
- Noções básicas da linguagem de programação JavaScript.
2. Criar um WebView simples da Web no Android
Como adicionar uma WebView no layout da atividade
Para adicionar uma WebView ao app no layout, adicione o seguinte código ao arquivo XML do layout da 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>;
Como adicionar uma WebView ao onCreate()
Para carregar uma página da Web na WebView, use loadUrl(). A WebView precisa ser criada em uma atividade em segundo plano. Por exemplo, vou implementar 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");
}
}
No entanto, antes que isso funcione, seu app precisa ter acesso à Internet. Para ter acesso à Internet, solicite a permissão INTERNET no arquivo de manifesto. Exemplo:
<uses-permission android:name="android.permission.INTERNET" />
Isso é tudo que você precisa para uma WebView básica que pode exibir uma página da Web.
Como usar o JavaScript em WebViews
Se a página da Web que você pretende carregar na WebView usa JavaScript, é preciso ativar o JavaScript para a WebView. Depois que o JavaScript tiver sido ativado, você também poderá criar interfaces entre o código do app e o código JavaScript.
Por padrão, o JavaScript fica desativado em uma WebView. Você pode ativar essa opção nas WebSettings anexadas à sua WebView. Você pode recuperar WebSettings com getSettings() e ativar o JavaScript com setJavaScriptEnabled().
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");
}
}
3. Implementar a interface de ponte JavaScript
Gerenciador do JavaScript
A primeira etapa para usar o Google Analytics em um WebView é criar funções JavaScript para transformar eventos e propriedades do usuário em código nativo. O exemplo a seguir mostra como fazer isso de modo compatível com o código nativo da Apple e do Android:
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 chamar o código nativo JavaScript no Android, implemente uma classe com os métodos marcados com @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 você configurou a interface JavaScript e pode começar a enviar eventos de análise.
4. Como enviar eventos pela interface
Como você pode ver aqui, minha WebView é muito simples. Ela tem três botões, dois que vão registrar um evento e o outro que vai registrar uma propriedade do usuário :
Quando eu clicar nos botões, o arquivo "script.js" será chamado e o seguinte código será executado :
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 Google Analytics.
5. Depurar eventos do WebView no Firebase
A depuração de eventos da WebView no seu app funciona da mesma forma que a depuração de qualquer parte nativa do 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
Depois disso, teste e veja seus eventos de WebView ganharem vida :
6. Parabéns
Parabéns! Você criou uma WebView no seu app Android. Agora é possível enviar e medir os principais eventos do funil no seu app que acontecem por meio de WebViews. Para aproveitar ao máximo, sugerimos que você se conecte ao Google Ads e importe esses eventos como conversões.
Você aprendeu
- Como enviar eventos da WebView para o Firebase
- Como configurar e criar uma WebView simples no Android