como validar um URL / nome de site em EditText no Android?

86

Eu quero tomar de entrada, uma URL ou apenas um nome de site como, www.google.com de EditTextno Android e no clique do usuário na Buttonsubmeter ou quando o EditTextperde o foco do URL deve ser validado, como é no formato " www.anyURL.com "...

Como posso fazer isso? Existe alguma funcionalidade embutida disponível no Android?

Preetam
fonte

Respostas:

279

Resposta curta

Use o padrão WEB_URL na classe de padrões

 Patterns.WEB_URL.matcher(potentialUrl).matches()

Ele retornará True se o URL for válido e falso se o URL for inválido .

Resposta longa

A partir da API Android nível 8, há um padrão WEB_URL . Citando a fonte, "corresponde à maior parte do RFC 3987". Se você visar um nível de API inferior, poderá simplesmente copiar o padrão da origem e incluí-lo em seu aplicativo. Presumo que você saiba como usar padrões e correspondências, então não entrarei em mais detalhes aqui.

Além disso, a classe URLUtil fornece alguns métodos úteis, por exemplo:

As descrições dos métodos não são muito elaboradas, portanto, provavelmente é melhor você olhar a fonte e descobrir qual deles se encaixa melhor no seu propósito.

Quanto a quando acionar a verificação de validação, existem várias possibilidades: você pode usar as funções de retorno de chamada EditText

ou use um TextWatcher , que acho que seria melhor.

NÃO USE URLUtil para validar o URL conforme abaixo.

 URLUtil.isValidUrl(url)

porque fornece strings como "http: //" como URL válido que não é verdadeiro

Dimi
fonte
16
Se você olhar a fonte de URLUtil, isValidUrl () e isHttpUrl () são basicamente iguais a startsWith ("http: //"), portanto, tome cuidado ao usá-los, pois você pode não obter os resultados desejados. Usar o padrão WEB_URL é muito mais adequado para validar urls.
Dave de
URLUtil.isValidUrl (downloadImageEditText.getText (). ToString ());
Prags
1
Mas no que diz respeito à entrada do usuário, o usuário não tentará digitar 'http: //' ou 'https: //' e apenas escreverá algo como www.google.com ou até mesmo google.com para um url, mas esses casos não estão sendo validados pela solução acima, acho que a solução precisa incluir a percepção do testador também.
Sri Krishna
1
CUIDADO: Patterns.WEB_URL não reconhece urls "localhost".
Artem Novikov
1
Patterns.WEB_URL não reconhece novos nomes de domínio. por exemplo, abc.xyz (com https: // como prefixo) (URL da Web do alfabeto)
Chintan Shah
22
/** 
* This is used to check the given URL is valid or not.
* @param url
* @return true if url is valid, false otherwise.
*/
private boolean isValidUrl(String url) {
    Pattern p = Patterns.WEB_URL;
    Matcher m = p.matcher(url.toLowerCase());
    return m.matches();
}
Shailendra Patil
fonte
4
O URL da Web deve estar em letras minúsculas, caso contrário, o padrão retornará falso. apenas postando, para que possa ajudar alguém ..
praveenb
@praveenb acima do trecho de código fornece www.website é válido, sem .com ou .in retorna verdadeiro. você pode dizer como fazer a validação para este cenário?
Parth Patel
Por que exatamente deve estar em minúsculas? Não diga apenas "isto é necessário", explique também porque é necessário!
Carsten Hagemann
4

No caso, em seu UnitTest, você conseguiu NullPointerExceptionusar em PatternsCompatvez de Patterns.

fun isFullPath(potentialUrl: String): Boolean {
    return PatternsCompat.WEB_URL.matcher(potentialUrl.toLowerCase(Locale.CANADA)).matches()
}

Além disso, percebi que esse método retorna truequando eu o passo Photo.jpg. Minha expectativa é false. Portanto, proponho o seguinte método em vez do acima.

fun isFullPath(potentialUrl: String): Boolean {
    try {
        URL(potentialUrl).toURI()
        return true
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return false
}
Hesam
fonte
Isso simplesmente fez o meu dia. Obrigado!
sparkly_frog
Obrigado pela dica sobre como usar PatternsCompat para executar testes.
Adi B
2

URLUtil.isValidUrl funcionará, pois existe desde o nível 1 da API.

galho
fonte
10
Essa não deve ser a resposta certa se você olhar o código para ela . É apenas verificar o esquema inicial da URL, não se a URL inteira é válida. Esta é provavelmente uma das piores validações de URL que já vi
Mike
1

Use este regex na validação do seu site

String WebUrl = "^((ftp|http|https):\\/\\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\\.[a-zA-Z]+)+((\\/)[\\w#]+)*(\\/\\w+\\?[a-zA-Z0-9_]+=\\w+(&[a-zA-Z0-9_]+=\\w+)*)?$";


//TODO for website validation

private boolean isValidate() 
{

        String website = txtWebsite.getText().toString().trim();
        if (website.trim().length() > 0) {
            if (!website.matches(WebUrl)) {
                //validation msg
                return false;
            }
        }
        return true;

}
Nidhi Savaliya
fonte
-4

Ou você poderia apenas usar o bom e velho Regex

Pattern urlRegex = Pattern.compile("((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:ww‌​w.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?‌​(?:[\w]*))?)");

Não estou dizendo que isso Patterns.WEB_URLé ruim, apenas torna mais fácil testar o que é correspondido e o que não é.

Matas Vaitkevicius
fonte