O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Como criar apps da Web na WebView

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 =
            "&lt;html&gt;&lt;body&gt;'%23' is the percent code for ‘#‘ &lt;/body&gt;&lt;/html&gt;"
    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 =
         "&lt;html&gt;&lt;body&gt;'%23' is the percent code for ‘#‘ &lt;/body&gt;&lt;/html&gt;";
    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 uma WebView 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.

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 fun onKeyDown(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 boolean onKeyDown(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.