Se você quer entregar um aplicativo da Web (ou apenas uma página da Web) como parte de um aplicativo cliente, é possível fazer isso usando WebView
. A classe WebView
é uma extensão da classe View
do Android, que permite exibir páginas da Web como parte do layout de atividades. Ela não inclui recursos de um navegador da Web completamente 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.
Usar WebView
pode ser útil quando você quer fornecer informações que talvez precisem ser atualizadas, por exemplo, como um contrato de usuário final ou um guia do usuário. No app para Android, você pode criar uma Activity
que contenha uma WebView
e usá-la para exibir o documento hospedado on-line.
A WebView
também pode ajudar caso o app forneça ao usuário dados que sempre exigem uma conexão de Internet para serem recuperados, como e-mails. Nesse caso, pode ser mais fácil criar no seu app para 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 mostra como dar os primeiros passos com a WebView
e como fazer outras coisas, como gerenciar a navegação nas páginas e vincular o JavaScript da página da Web ao código do cliente no seu app para Android.
Como adicionar uma WebView ao app
Para adicionar uma WebView
ao app, você pode incluir o elemento <WebView>
no layout da atividade ou definir toda a janela Atividade como uma WebView
em onCreate()
.
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:
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
Para carregar uma página da Web na WebView
, use loadUrl()
. Exemplo:
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");
Como adicionar uma WebView ao onCreate()
Para adicionar uma 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 com:
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");
Observação: há restrições quanto ao que esse HTML pode fazer. Consulte loadData()
e loadDataWithBaseURL()
para ver mais informações sobre as opções de codificação.
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:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
Isso é tudo que você precisa para uma WebView
básica que pode exibir uma página da Web.
Além disso, você pode personalizar sua WebView
modificando o seguinte:
- Ativando a compatibilidade de tela cheia com o
WebChromeClient
. Essa classe também é chamada quando umaWebView
precisa de permissão para mudar a IU do app host, como ao criar ou fechar janelas e enviar caixas de diálogo JavaScript ao usuário. Para saber mais sobre a depuração nesse contexto, leia Como depurar apps da Web. - Gerenciando eventos que afetam a renderização de conteúdo, como erros em envios de formulários ou navegação com o
WebViewClient
. Você também pode usar essa subclasse para interceptar o carregamento do URL. - Ativando o JavaScript ao modificar as
WebSettings
. - Usando o JavaScript para acessar objetos do framework do Android que foram injetados em uma
WebView
.
Como usar o JavaScript na WebView
Se a página da Web que você pretende carregar na WebView
usa JavaScript, você precisa ativar o JavaScript para sua . Depois que o JavaScript tiver sido ativado, você também poderá criar interfaces entre o código do app e o código JavaScript.
Como ativar o JavaScript
Por padrão, o JavaScript fica desativado em uma WebView
. Você pode ativá-lo por meio das WebSettings
anexadas à WebView
. Você pode recuperar WebSettings
com getSettings()
e ativar o JavaScript com setJavaScriptEnabled()
.
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 para 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 é, na verdade, seu app para Android.
Como vincular o código JavaScript ao código do Android
Ao desenvolver um aplicativo da Web projetado especificamente para a WebView
no seu app para 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 exibir uma 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 JavaScript e um nome de interface que o JavaScript possa chamar para acessar a classe.
Por exemplo, você pode incluir a seguinte classe no app para 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(); } }
Atenção: se você definiu sua targetSdkVersion
como 17 ou mais, precisará adicionar a anotação @JavascriptInterface
a todo método que quiser disponibilizar para o JavaScript (o método também tem que ser público). Se você não fornecer a anotação, o método não poderá ser acessado pela página da Web quando executado no Android 4.2 ou em versões posteriores.
Nesse exemplo, a classe WebAppInterface
permite que a página da Web crie uma mensagem Toast
usando o método showToast()
.
Você pode vincular essa classe ao JavaScript executado na WebView
com addJavascriptInterface()
e nomear a interface Android
. Exemplo:
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 clica 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, ao clicar no botão, a função showAndroidToast()
usa a interface Android
para chamar o método WebAppInterface.showToast()
.
Observação: o objeto vinculado ao JavaScript é executado em outra linha de execução em vez daquela em que ele foi criado.
Atenção: usar addJavascriptInterface()
permite que o JavaScript controle seu app para Android. Isso pode ser um recurso muito útil ou um problema de segurança perigoso. Quando o HTML na WebView
não for confiável, por exemplo, todo o HTML ou parte dele foi fornecido por uma pessoa ou um processo desconhecido, o invasor poderá incluir um HTML que execute o código do cliente e possivelmente qualquer código que o invasor escolher. Assim, não use addJavascriptInterface()
, a menos que você tenha criado todos os códigos HTML e JavaScript exibidos na sua WebView
. Além disso, não permita que o usuário navegue para outras páginas da Web que não sejam suas dentro da WebView
. Em vez disso, permita que o aplicativo de navegação padrão do usuário abra links externos. Por padrão, o navegador da Web do usuário abre todos os URLs, então só tome cuidado se você gerenciar a navegação nas páginas conforme descrito na seção a seguir.
Como gerenciar a navegação nas páginas
Quando o usuário clica em um link de uma página da Web na sua WebView
, o comportamento padrão é que o Android abra 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
.
Observação: por motivos de segurança, o app de navegação do sistema não compartilha os dados de aplicativo dele com seu app.
Para abrir os links clicados pelo usuário, forneça um WebViewClient
para a WebView
usando o setWebViewClient()
. Exemplo:
Kotlin
val myWebView: WebView = findViewById(R.id.webview)
myWebView.webViewClient
= WebViewClient()
Java
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient
(MyWebViewClient);
Pronto. Agora, todos os links em que o usuário clicar 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 método shouldOverrideUrlLoading()
. Exemplo:
Kotlin
private class MyWebViewClient : WebViewClient() {
override fun shouldOverrideUrlLoading
(view: WebView?, url: String?): Boolean {
if (Uri.parse(url).host == "www.example.com") {
// This is my web site, so do not override; let my WebView load the page
return false
}
// Otherwise, the link is not for a page on my 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, String url) {
if ("www.example.com".equals(Uri.parse(url).getHost())) {
// This is my website, so do not override; let my WebView load the page
return false;
}
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
Em seguida, crie uma instância desse novo WebViewClient
para a 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 clicar em um link, o sistema chamará shouldOverrideUrlLoading()
, que verificará se o host do URL corresponde a um domínio específico (conforme definido acima). Se corresponder, o método retornará como falso para 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 a atividade padrão para gerenciar URLs, que retorna para o navegador da Web padrão do usuário.
Como 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, veja como sua Activity
pode usar o botão Voltar do dispositivo para navegar para itens anteriores do histórico:
Kotlin
override funonKeyDown
(keyCode: Int, event: KeyEvent?): Boolean { // Check if the key event was the Back button and if there's history if (keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack
()) { myWebView.goBack() return true } // If it wasn't the Back key or there's no web page history, bubble up to the default // system behavior (probably exit the activity) return super.onKeyDown(keyCode, event) }
Java
@Override public booleanonKeyDown
(int keyCode, KeyEvent event) { // Check if the key event was the Back button and if there's history if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack
()) { myWebView.goBack
(); return true; } // If it wasn't the Back key or there's no web page history, bubble up to the default // system behavior (probably exit the activity) return super.onKeyDown(keyCode, event); } }
O método canGoBack()
retornará como verdadeiro se houver mesmo 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, quando o usuário chegar ao final do histórico, goBack()
ou goForward()
não terão efeito.
Como 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 farão 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 carregará 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 alterações de configuração.
Como 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 desejado de um link. Você pode personalizar seu WebChromeClient
para fornecer seu próprio comportamento ao abrir várias janelas.
Atenção: 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.
Lembre-se de que essa lógica também impede que as páginas que usem target="_blank"
nos links sejam carregadas.