Use WebView para entregar um aplicativo da Web ou uma página da Web como parte de um
app cliente. A classe WebView é uma extensão da classe View
do Android que permite mostrar páginas da Web como parte do layout de atividades. Ela não inclui os recursos de um navegador da Web totalmente desenvolvido, como controles de navegação ou uma barra de endereço. Por padrão, tudo o que WebView faz é mostrar uma página da Web.
WebView pode ajudar você a fornecer informações no app que talvez precisem ser atualizadas, por exemplo, um contrato de usuário final ou um guia do usuário. No app Android,
você pode criar um Activity que contenha um
WebView, e usá-lo para mostrar o documento hospedado on-line.
WebView também pode ajudar quando o app fornece ao usuário dados que exigem uma conexão de Internet para serem recuperados, como e-mails. Nesse caso, pode ser mais fácil criar no seu app Android uma WebView que mostre uma página da web com todos os dados do usuário em vez de executar uma solicitação de rede, analisar os dados e renderizá-los em um layout do Android. Em vez disso, você pode criar uma página da Web personalizada para dispositivos Android e implementar no próprio aplicativo uma WebView que carregue essa página.
Este documento descreve como começar a usar WebView, como vincular o JavaScript da página da Web ao código do lado do cliente no seu app Android, como gerenciar a navegação nas páginas e como gerenciar janelas ao usar WebView.
Trabalhar com o WebView em versões anteriores do Android
Para usar com segurança os recursos mais recentes do WebView no dispositivo em que o app está
sendo executado, adicione a biblioteca AndroidX Webkit. Essa é uma biblioteca estática que pode ser adicionada ao aplicativo para usar APIs android.webkit que não estão disponíveis para versões anteriores da plataforma.
Adicione-a ao arquivo build.gradle da seguinte maneira:
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
Groovy
dependencies { implementation ("androidx.webkit:webkit:1.8.0") }
Confira o WebView exemplo no GitHub para mais detalhes.
Adicionar um WebView ao app
Para adicionar um WebView ao app, você pode incluir o elemento <WebView> no
layout da atividade ou definir toda a janela Activity como um WebView em
onCreate().
Adicionar um WebView no layout da atividade
Para adicionar um WebView ao app no layout, adicione o seguinte código ao arquivo XML do layout da atividade:
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
Para carregar uma página da Web no WebView, use loadUrl(), conforme mostrado no
exemplo a seguir:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.loadUrl("http://www.example.com")
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.loadUrl("http://www.example.com");
Adicionar um WebView ao onCreate()
Para adicionar um WebView ao app no método onCreate() de uma atividade, use uma lógica semelhante à seguinte:
Kotlin
val myWebView = WebView(activityContext) setContentView(myWebView)
Java
WebView myWebView = new WebView(activityContext); setContentView(myWebView);
Em seguida, carregue a página:
Kotlin
myWebView.loadUrl("http://www.example.com")
Java
myWebView.loadUrl("https://www.example.com");
Ou carregue o URL a partir de uma string HTML:
Kotlin
// Create an unencoded HTML string, then convert the unencoded HTML string into // bytes. Encode it with base64 and load the data. val unencodedHtml = "<html><body>'%23' is the percent code for ‘#‘ </body></html>"; val encodedHtml = Base64.encodeToString(unencodedHtml.toByteArray(), Base64.NO_PADDING) myWebView.loadData(encodedHtml, "text/html", "base64")
Java
// Create an unencoded HTML string, then convert the unencoded HTML string into // bytes. Encode it with base64 and load the data. String unencodedHtml = "<html><body>'%23' is the percent code for ‘#‘ </body></html>"; String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING); myWebView.loadData(encodedHtml, "text/html", "base64");
Seu app precisa ter acesso à Internet. Para ter acesso à Internet, solicite a
INTERNET permissão no arquivo de manifesto, conforme mostrado no
exemplo a seguir:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
Você pode personalizar seu WebView fazendo qualquer uma das seguintes ações:
- Ativar o suporte a tela cheia usando
WebChromeClient. Essa classe também é chamada quando umaWebViewprecisa de permissão para mudar a IU do app host, como ao criar ou fechar janelas ou enviar caixas de diálogo JavaScript ao usuário. Para saber mais sobre a depuração nesse contexto, leia Depurar apps da Web. - Gerenciar eventos que afetam a renderização de conteúdo, como erros em envios de formulários
ou navegação usando
WebViewClient. Você também pode usar essa subclasse para interceptar o carregamento do URL. - Ativar o JavaScript ao modificar
WebSettings. - Usar o JavaScript para acessar objetos do framework do Android que foram injetados em uma
WebView.
Usar JavaScript no WebView
Se a página da Web que você quer carregar na sua WebView usa JavaScript, você precisa ativar o JavaScript para sua WebView. Depois de ativar o JavaScript, você pode criar interfaces entre o código do app e o código JavaScript.
Ativar o JavaScript
Por padrão, o JavaScript fica desativado em uma WebView. Você pode ativá-lo por meio das WebSettings anexadas à WebView. Recupere WebSettings com
getSettings() e ative o JavaScript com
setJavaScriptEnabled().
Confira este exemplo:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.settings.javaScriptEnabled = true
Java
WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);
A WebSettings fornece acesso a uma variedade de outras configurações que podem ser úteis. Por exemplo, se você está desenvolvendo um aplicativo da Web projetado
especificamente para a WebView no seu app Android, você pode definir uma string de
user agent personalizado com setUserAgentString() e consultar o user
agent personalizado na página da Web para confirmar se o cliente que está solicitando a página da Web é
seu app Android.
Vincular o código JavaScript ao código do Android
Ao desenvolver um aplicativo da Web projetado especificamente para a WebView no seu app Android, você pode criar interfaces entre o código JavaScript e o código do Android do lado do cliente. Por exemplo, seu código JavaScript pode chamar um método no
código do Android para mostrar um Dialog em vez de usar a função
alert() do JavaScript.
Para vincular uma nova interface entre seu código do Android e JavaScript, chame
addJavascriptInterface(), transmitindo uma instância de classe a ele para vincular ao seu
JavaScript e um nome de interface que seu JavaScript possa chamar para acessar a
classe.
Para saber mais sobre a comunicação entre JavaScript e código nativo, incluindo APIs mais modernas e seguras, consulte Acessar APIs nativas com JSBridge.
Por exemplo, você pode incluir a seguinte classe no app Android:
Kotlin
/** Instantiate the interface and set the context. */ class WebAppInterface(private val mContext: Context) { /** Show a toast from the web page. */ @JavascriptInterface fun showToast(toast: String) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show() } }
Java
public class WebAppInterface { Context mContext; /** Instantiate the interface and set the context. */ WebAppInterface(Context c) { mContext = c; } /** Show a toast from the web page. */ @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } }
Neste exemplo, a classe WebAppInterface permite que a página da Web crie uma
Toast mensagem usando o método showToast().
Você pode vincular essa classe ao JavaScript executado na WebView com addJavascriptInterface(), conforme mostrado no exemplo a seguir:
Kotlin
val webView: WebView = findViewById(R.id.webview) webView.addJavascriptInterface(WebAppInterface(this), "Android")
Java
WebView webView = (WebView) findViewById(R.id.webview); webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Isso cria uma interface chamada Android para o JavaScript em execução na WebView. Nesse ponto, seu aplicativo da Web terá acesso à classe WebAppInterface. Por exemplo, veja alguns códigos HTML e JavaScript que criam uma mensagem de aviso usando a nova interface quando o usuário toca em um botão:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>
Não é necessário inicializar a interface Android do JavaScript. A WebView disponibiliza a interface automaticamente para a página da Web. Assim, quando um usuário
toca no botão, a função showAndroidToast() usa a interface Android para chamar o método WebAppInterface.showToast().
Gerenciar a navegação nas páginas
Quando o usuário toca em um link de uma página da Web na sua WebView, por padrão, o Android abre um app que gerencia URLs. Geralmente, o navegador da Web padrão é aberto e carrega o URL de destino. No entanto, você pode modificar esse comportamento para sua WebView e fazer com que os links sejam abertos na WebView. Você pode permitir que o usuário volte e avance no histórico de páginas da Web mantido pela WebView.
Para abrir os links tocados pelo usuário, forneça um WebViewClient para a WebView
usando o setWebViewClient(). Todos os links em que o usuário tocar serão carregados na WebView. Se quiser ter mais controle sobre onde um link clicado será carregado, crie seu
próprio WebViewClient que modifica o shouldOverrideUrlLoading()
método. O exemplo a seguir pressupõe que MyWebViewClient seja uma classe interna de Activity.
Kotlin
private class MyWebViewClient : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { if (Uri.parse(url).host == "www.example.com") { // This is your website, so don't override. Let your WebView load // the page. return false } // Otherwise, the link isn't for a page on your site, so launch another // Activity that handles URLs. Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { startActivity(this) } return true } }
Java
private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { if ("www.example.com".equals(request.getUrl().getHost())) { // This is your website, so don't override. Let your WebView load the // page. return false; } // Otherwise, the link isn't for a page on your site, so launch another // Activity that handles URLs. Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); startActivity(intent); return true; } }
Em seguida, crie uma instância desse novo WebViewClient para o WebView:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.webViewClient = MyWebViewClient()
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
Agora, quando o usuário tocar em um link, o sistema chamará o método shouldOverrideUrlLoading(), que verificará se o host do URL corresponde a um domínio específico, conforme definido no exemplo anterior. Se corresponder, o método retornará como falso e não modificará o carregamento do URL. Isso permite que WebView carregue o URL como de costume.
Se o host do URL não for correspondente, um Intent será criado para iniciar o
padrão Activity para gerenciar URLs, que retorna para o navegador da Web padrão do usuário.
Gerenciar URLs personalizados
WebView aplica restrições ao solicitar recursos e resolver links que usam um esquema de URL personalizado. Por exemplo, se você implementar callbacks como
shouldOverrideUrlLoading() ou shouldInterceptRequest(), então
WebView os invocará apenas para URLs válidos.
Por exemplo, a WebView pode não chamar seu método shouldOverrideUrlLoading() para links como este:
<a href="showProfile">Show Profile</a>
URLs inválidos, como o mostrado no exemplo anterior, são processados de forma inconsistente na WebView. Por isso, recomendamos usar um URL bem formado.
Você pode usar um esquema personalizado ou um URL HTTPS para um domínio controlado pela sua organização.
Em vez de usar uma string simples em um link, como no exemplo anterior, você pode usar um esquema personalizado como o seguinte:
<a href="example-app:showProfile">Show Profile</a>
Em seguida, você pode gerenciar esse URL no método shouldOverrideUrlLoading(), desta forma:
Kotlin
// The URL scheme must be non-hierarchical, meaning no trailing slashes. const val APP_SCHEME = "example-app:" override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return if (url?.startsWith(APP_SCHEME) == true) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length), "UTF-8") respondToData(urlData) true } else { false } }
Java
// The URL scheme must be non-hierarchical, meaning no trailing slashes. private static final String APP_SCHEME = "example-app:"; @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith(APP_SCHEME)) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length()), "UTF-8"); respondToData(urlData); return true; } return false; }
A API shouldOverrideUrlLoading() é destinada principalmente a iniciar intents para URLs específicos. Ao implementá-la, retorne false para URLs que a WebView processa. No entanto, você não está limitado a iniciar intents. É possível substituir o lançamento de intents por qualquer comportamento personalizado nos exemplos de código anteriores.
Navegar pelo histórico da página da Web
Quando sua WebView modifica o carregamento do URL, ela acumula automaticamente um histórico de páginas da Web visitadas. Você pode voltar e avançar no
histórico com goBack() e goForward().
Por exemplo, o código a seguir mostra como sua Activity pode usar o botão Voltar do dispositivo para navegar para itens anteriores do histórico:
Kotlin
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { // Check whether the key event is the Back button and if there's history. if (keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack()) { myWebView.goBack() return true } // If it isn't the Back button or there isn't web page history, bubble up to // the default system behavior. Probably exit the activity. return super.onKeyDown(keyCode, event) }
Java
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { // Check whether the key event is the Back button and if there's history. if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) { myWebView.goBack(); return true; } // If it isn't the Back button or there's no web page history, bubble up to // the default system behavior. Probably exit the activity. return super.onKeyDown(keyCode, event); }
Se o app usa o AndroidX AppCompat 1.6.0 ou mais recente, você pode simplificar ainda mais o snippet anterior:
Kotlin
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack() } }
Java
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack(); } }
O método canGoBack() retorna verdadeiro se houver um histórico da página da Web para o
usuário visitar. Da mesma forma, você pode usar canGoForward() para verificar se
há um histórico de avanço. Se você não fizer essa verificação, depois que o usuário chegar ao final do histórico, goBack() e goForward() não terão efeito.
Gerenciar as mudanças na configuração do dispositivo
No ambiente de execução, mudanças no estado da atividade ocorrem quando a configuração de um dispositivo é modificada. Por exemplo, quando os usuários giram o dispositivo ou dispensam um editor de método de entrada (IME, na sigla em inglês). Essas mudanças fazem com que a atividade de um objeto WebView seja destruída e uma nova atividade seja criada, criando também um novo objeto WebView que carrega o URL do objeto destruído. Para modificar o comportamento padrão da atividade, mude a forma como ela gerencia mudanças de orientation no manifesto. Para saber mais
sobre como gerenciar mudanças de configuração no ambiente de execução, leia Gerenciar mudanças de configuração.
Gerenciar janelas
Por padrão, as solicitações para abrir novas janelas são ignoradas. Isso acontece independentemente de serem abertas por JavaScript ou pelo atributo de destino de um link. Você pode personalizar seu WebChromeClient para fornecer seu próprio comportamento ao abrir várias janelas.
Para manter seu app mais seguro, é melhor evitar que pop-ups e novas janelas sejam abertos. A maneira mais segura de implementar esse comportamento é transmitindo "true" para
setSupportMultipleWindows(), mas sem modificar o método
onCreateWindow(), do qual setSupportMultipleWindows() é dependente.
Essa lógica impede que as páginas que usem target="_blank" nos links sejam carregadas.