ChatGPT解决这个技术问题 Extra ChatGPT

URL encoding in Android

How do you encode a URL in Android?

I thought it was like this:

final String encodedURL = URLEncoder.encode(urlAsString, "UTF-8");
URL url = new URL(encodedURL);

If I do the above, the http:// in urlAsString is replaced by http%3A%2F%2F in encodedURL and then I get a java.net.MalformedURLException when I use the URL.


K
Khal91

You don't encode the entire URL, only parts of it that come from "unreliable sources".

Java: String query = URLEncoder.encode("apples oranges", "utf-8"); String url = "http://stackoverflow.com/search?q=" + query;

Kotlin: val query: String = URLEncoder.encode("apples oranges", "utf-8") val url = "http://stackoverflow.com/search?q=$query"

Alternatively, you can use Strings.urlEncode(String str) of DroidParts that doesn't throw checked exceptions.

Or use something like

String uri = Uri.parse("http://...")
                .buildUpon()
                .appendQueryParameter("key", "val")
                .build().toString();

What if the whole url is unreliable? Should I encode everything except the protocol? I kind of expected a convenience method to do this.
Then it's just a broken url. The idea is to prevent the query part from breaking the url.
@hgpc - take a look at section 3 of RFC3986 (tools.ietf.org/html/rfc3986#section-3). It tells you how to encode the various portions of a URI. Unfortunately each portion of the URI (host, path, query, etc.) has slightly different encoding rules.
This is fine in you are just dealing with a specific part of a URL and you know how to construct or reconstruct the URL. For a more general approach which can handle any url string, see my answer below.
Why am I getting a deprecation warning using this? Used Uri.encode(query); instead.
C
Craig B

I'm going to add one suggestion here. You can do this which avoids having to get any external libraries.

Give this a try:

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

You can see that in this particular URL, I need to have those spaces encoded so that I can use it for a request.

This takes advantage of a couple features available to you in Android classes. First, the URL class can break a url into its proper components so there is no need for you to do any string search/replace work. Secondly, this approach takes advantage of the URI class feature of properly escaping components when you construct a URI via components rather than from a single string.

The beauty of this approach is that you can take any valid url string and have it work without needing any special knowledge of it yourself.


This should be the correct answer. this is the formal and clear way to do this
It can also be a good idea to urldecode urlStr before sending it to the URL constructor. URLDecoder.decode(urlStr)
Exact answer.Thank you so much.You made my day
@berserk If it is already encoded, don't encode it. You shouldn't get into a state where it is partially encoded, or you aren't sure whether it is or isn't encoded.
This method doesn't encode characters like ğ to %C4%9F. Accepted one encodes!
t
tanutapi

For android, I would use String android.net.Uri.encode(String s)

Encodes characters in the given string as '%'-escaped octets using the UTF-8 scheme. Leaves letters ("A-Z", "a-z"), numbers ("0-9"), and unreserved characters ("_-!.~'()*") intact. Encodes all other characters.

Ex/

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);

Unfortunately Uri.encode("a=1&b=1") produces a%3D1%26b%3D1 but expected a=1&b=1
@loentar That's the expected result. If the user enters a=1&b=1 as a query, you want to query exactly that.
How different this with URLEncoder.encode(StringHere,"UTF-8")
@stuckedoverflow For one thing, Uri.encode(str) does not throw a checked exception unlike URLEncoder.encode(str,"UTF-8")
J
Jedo

Also you can use this

private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
String urlEncoded = Uri.encode(path, ALLOWED_URI_CHARS);

it's the most simple method


this is not the best solution, but it is definitely a nice quick fix...thanx
This is the quickest fix when the whole URL is unreliable. Thanks!
Are you sure the % should be allowed? Should it not be encoded?
How to encode this url to be possible to share and then user be able to open the link and see the page : yazd20.com//News/2015/11/استند-آب-كمدي-حسن-ريوندي-در-يزد.html
T
Thiago
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

E
Elango

you can use below methods

public static String parseUrl(String surl) throws Exception
{
    URL u = new URL(surl);
    return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}

or

public String parseURL(String url, Map<String, String> params)
{
    Builder builder = Uri.parse(url).buildUpon();
    for (String key : params.keySet())
    {
        builder.appendQueryParameter(key, params.get(key));
    }
    return builder.build().toString();
}

the second one is better than first.


A
Ali Jafari

Find Arabic chars and replace them with its UTF-8 encoding. some thing like this:

for (int i = 0; i < urlAsString.length(); i++) {
    if (urlAsString.charAt(i) > 255) {
        urlAsString = urlAsString.substring(0, i) + URLEncoder.encode(urlAsString.charAt(i)+"", "UTF-8") + urlAsString.substring(i+1);
    }
}
encodedURL = urlAsString;