如何在 Android 的 EditText 中验证 URL/网站名称?

我想采取输入,一个网址或只是一个网站名称,如 Www.google.comEditText在安卓和用户点击提交的 Button或当 EditText失去重点的网址应验证, 就像是“ Www.anyURL.com”格式。

我如何做到这一点? 有没有任何内置的功能,可在安卓?

60029 次浏览

Short answer

Use WEB_URL pattern in Patterns Class

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

It will return True if URL is valid and false if URL is invalid.

Long answer

As of Android API level 8 there is a WEB_URL pattern. Quoting the source, it "match[es] most part of RFC 3987". If you target a lower API level you could simply copy the pattern from the source and include it in your application. I assume you know how to use patterns and matchers, so I'm not going into more details here.

Also the class URLUtil provides some useful methods, e.g:

The descriptions of the methods are not very elaborate, therefore you are probably best of looking at the source and figuring out which one fits your purpose best.

As for when to trigger the validation check, there are multiple possibilities: you could use the EditText callback functions

or use a TextWatcher, which I think would be better.

DON'T USE URLUtil to validate the URL as below.

 URLUtil.isValidUrl(url)

because it gives strings like "http://" as valid URL which isn't true

URLUtil.isValidUrl will work since it exists since api level 1.

/**
* 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();
}

Or you could just use good old 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]*))?)");

I am not saying that Patterns.WEB_URL is bad, it just it makes it easy to test what gets matched and what does not.

Use this regex on your website validation

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;


}

In case, in your UnitTest, you got NullPointerException then use PatternsCompat instead of Patterns.

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

Also, I realized that this method returns true when I pass it Photo.jpg. My expectation is false. Therefore, I propose following method instead of the above.

fun isFullPath(potentialUrl: String): Boolean {
try {
URL(potentialUrl).toURI()
return true
} catch (e: Exception) {
e.printStackTrace()
}
return false
}