O `shouldOverrideUrlLoading` está realmente obsoleto? O que posso usar em vez disso?

138

"ShouldOverrideUrlLoading" está realmente obsoleto? Se sim, o que posso usar?

Parece que shouldOverrideUrlLoadingfoi descontinuado para o Android N e preciso fazer com que um aplicativo funcione desde a API 19 até o mais recente, que é o Android N (beta), uso alguns recursos novos no Android N (como o Data Saver), para segmentar O Marshmallow não ajudará com o problema, pois preciso usar esses novos recursos. Aqui está a parte do código que uso:

public boolean shouldOverrideUrlLoading(WebView webview, String url) {
    if (url.startsWith("http:") || url.startsWith("https:")) {
        ...
    } else if (url.startsWith("sms:")) {
        ...
    }
    ...
}

E esta é a mensagem que o Android Studio me deu:

Substitui o método obsoleto em 'android.webkit.WebViewClient' Esta inspeção relata onde o código obsoleto é usado no escopo de inspeção especificado.

O Google não diz nada sobre essa depreciação .

Gostaria de saber se o uso @SuppressWarnings("deprecation")me permitirá trabalhar em todos os dispositivos, desde a API 19 até o Android N Beta mais recente (e sua versão final, quando for lançado), não posso testá-lo sozinho, nunca usei isso e preciso ter certeza que funciona, então, qualquer um pode dizer?

Minion
fonte
1
Existem duas versões desse método de retorno de chamada. O antigo está obsoleto. Nesse caso, "reprovado" significa "ei, temos outra coisa que você pode tentar, se for apropriado para você". O retorno de chamada antigo deve continuar funcionando, pois é necessário para versões anteriores ao N do Android.
CommonsWare
Primeiro, obrigado pelo comentário, a versão que estou usando é boa, já que é exatamente a mesma do Android Developer Docs, exceto pelo nome da string, eles usaram "view" e eu usei "webview" , o resto é o mesmo; então, por que devo fazer para que ele funcione em todas as versões?
Minion

Respostas:

95

A versão que estou usando, acho que é boa, já que é exatamente a mesma do Android Developer Docs, exceto pelo nome da string, eles usaram "view" e eu usei "webview", o resto é o mesmo

Não não é.

O novo no N Developer Preview possui esta assinatura de método:

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)

O que é suportado por todas as versões do Android, incluindo N, tem esta assinatura de método:

public boolean shouldOverrideUrlLoading(WebView view, String url)

Então, por que devo fazer para que ele funcione em todas as versões?

Substitua o que foi descontinuado, aquele que leva a Stringcomo segundo parâmetro.

CommonsWare
fonte
Olá, e obrigado pela resposta, que ainda não é compatível desde a API 19, porque para obter a string da URL eu tenho que usar "url.getUrl (). ToString ()" e foi adicionada na API 21, qualquer maneira de fazer funciona desde API 19?
Minion
3
@Minion: "que ainda não é compatível desde a API 19" - sim, é. "porque para obter a string da URL, preciso usar" url.getUrl (). toString () "" - não, a URL é fornecida como o segundo parâmetro, na forma de String. Por exemplo, este aplicativo de amostra , compilado no nível 19 da API, funciona bem, como em um Nexus 5. com Android 6.0.
CommonsWare
Olá, o uso da "solicitação WebResourceRequest" não possui um parâmetro String
Minion
2
@Minion: Correto. Isso funciona apenas no Android N (e, presumivelmente, mais alto). Você perguntou "então por que devo fazer para que funcione em todas as versões?". Eu lhe disse para substituir o obsoleto, aquele que leva a Stringcomo segundo parâmetro. Por exemplo, o aplicativo de exemplo ao qual
vinculei
6
Se você quiser ser à prova de futuro, poderá substituir ambos os métodos. Dessa forma, seu aplicativo continuará a trabalhar com <21, mas você estará pronto para usar assim que descontinuar totalmente o método antigo. E você não terá que se preocupar getUrl()porque o novo método só será chamado para 24+
yuval
187

Documentar em detalhes para futuros leitores:

A resposta curta é que você precisa substituir os dois métodos. O shouldOverrideUrlLoading(WebView view, String url)método foi descontinuado na API 24 e o shouldOverrideUrlLoading(WebView view, WebResourceRequest request)método foi adicionado na API 24. Se você estiver direcionando versões mais antigas do Android, precisará do método anterior e se estiver direcionando 24 (ou mais tarde, se alguém estiver lendo isso em um futuro distante) é aconselhável substituir o último método também.

A seguir, está o esqueleto de como você faria isso:

class CustomWebViewClient extends WebViewClient {

    @SuppressWarnings("deprecation")
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        final Uri uri = Uri.parse(url);
        return handleUri(uri);
    }

    @TargetApi(Build.VERSION_CODES.N)
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        final Uri uri = request.getUrl();
        return handleUri(uri);
    }

    private boolean handleUri(final Uri uri) {
        Log.i(TAG, "Uri =" + uri);
        final String host = uri.getHost();
        final String scheme = uri.getScheme();
        // Based on some condition you need to determine if you are going to load the url 
        // in your web view itself or in a browser. 
        // You can use `host` or `scheme` or any part of the `uri` to decide.
        if (/* any condition */) {
            // Returning false means that you are going to load this url in the webView itself
            return false;
        } else {
            // Returning true means that you need to handle what to do with the url
            // e.g. open web page in a Browser
            final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
            return true;
        }
    }
}

Assim como shouldOverrideUrlLoading, você pode criar uma abordagem semelhante para o shouldInterceptRequestmétodo.

Henry
fonte
6
@ webo80 Na verdade, ele é adicionado na API24 / N developer.android.com/reference/android/webkit/…
Henry
3
É melhor usar @RequiresApiem vez de @TargetApi aqui para uso futuro
Hibbem
1
O problema com substituindo ambos os métodos, pelo menos, com shouldInterceptRequest, é que em dispositivos Android N + são ambos invocado e você vai ser lidar com cada uri duas vezes! Para remediar isso, adicionei uma Build.VERSION.SDK_INT < Build.VERSION_CODES.Ncondição na versão preterida.
Jonik
8
@JohnLee Normalmente, apenas um dos métodos será chamado. Mas se você colocar super. shouldOverrideUrlLoading(view,request)o método não reprovado, sim, o método não reprovado e o obsoleto serão chamados. Isso ocorre porque a implementação padrão do método não preterido é chamar internamente o método preterido. Basta dar uma olhada no WebViewClient.shouldOverrideUrlLoading(WebView view, WebResourceRequest request). Portanto, certifique-se de não ligar super.shouldOverrideUrlLoading().
Henry
1
Apenas salientando que a funcionalidade de ter os dois métodos chamados não está documentada. Eu não confiaria nisso sempre, pois não é mencionado na documentação.
Austyn Mahoney
15

Usar

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return shouldOverrideUrlLoading(view, request.getUrl().toString());
}
Saleem Kalro
fonte
2
é view.loadUrl (request.getUrl (). toString ());
precisa saber é o seguinte
seu trabalho, mas se usarmos de volta, em seguida, ele vai fechar o aplicativo
MRRaja
4
isso não iria apoiar api menos de 21
mumair
-1

Implemente métodos preteridos e não preteridos, como abaixo. O primeiro é lidar com o nível 21 da API e superior, o segundo é lidar com o nível inferior à API 21

webViewClient = object : WebViewClient() {
.
.
        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
            parseUri(request?.url)
            return true
        }

        @SuppressWarnings("deprecation")
        override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
            parseUri(Uri.parse(url))
            return true
        }
}
emre
fonte
1
Parece ser uma cópia parcial da resposta de Henry, mas descarta o valor retornado por Uri.parsee parseUri. Novas respostas devem adicionar novas informações úteis e novos insights ao tópico.
AdrianHHH 25/07/19
Me fez perder tempo desde api só é obsoleta na API 24 e não 21
Gustavo Baiocchi Costa