Android: how to parse URL String with spaces to URI object?

JavaAndroidUrlUriHttprequest

Java Problem Overview


I have a string representing an URL containing spaces and want to convert it to an URI object. If I simply try to create it via

String myString = "http://myhost.com/media/File Name that has spaces inside.mp3";
URI myUri = new URI(myString);

it gives me

java.net.URISyntaxException: Illegal character in path at index X

where index X is the position of the first space in the URL string.

How can i parse myString into a URI object?

Java Solutions


Solution 1 - Java

You should in fact URI-encode the "invalid" characters. Since the string actually contains the complete URL, it's hard to properly URI-encode it. You don't know which slashes / should be taken into account and which not. You cannot predict that on a raw String beforehand. The problem really needs to be solved at a higher level. Where does that String come from? Is it hardcoded? Then just change it yourself accordingly. Does it come in as user input? Validate it and show error, let the user solve itself.

At any way, if you can ensure that it are only the spaces in URLs which makes it invalid, then you can also just do a string-by-string replace with %20:

URI uri = new URI(string.replace(" ", "%20"));

Or if you can ensure that it's only the part after the last slash which needs to be URI-encoded, then you can also just do so with help of android.net.Uri utility class:

int pos = string.lastIndexOf('/') + 1;
URI uri = new URI(string.substring(0, pos) + Uri.encode(string.substring(pos)));

Do note that URLEncoder is insuitable for the task as it's designed to encode query string parameter names/values as per application/x-www-form-urlencoded rules (as used in HTML forms). See also https://stackoverflow.com/questions/10786042/java-url-encoding-of-query-string-parameters.

Solution 2 - Java

java.net.URLEncoder.encode(finalPartOfString, "utf-8");

This will http://www.w3schools.com/TAGS/ref_urlencode.asp">URL-encode</a> the string.

finalPartOfString is the part after the last slash - in your case, the name of the song, as it seems.

Solution 3 - Java

To handle spaces, @, and other unsafe characters in arbitrary locations in the url path, Use Uri.Builder in combination with a local instance of URL as I have described here:

private Uri.Builder builder;
public Uri getUriFromUrl(String thisUrl) {
    URL url = new URL(thisUrl);
    builder =  new Uri.Builder()
                            .scheme(url.getProtocol())
                            .authority(url.getAuthority())
                            .appendPath(url.getPath());
    return builder.build();
}

Solution 4 - Java

URL url = Test.class.getResource(args[0]);  // reading demo file path from												     
                                            // same location where class 									
File input=null;
try {
	input = new File(url.toURI());
} catch (URISyntaxException e1) {
	// TODO Auto-generated catch block
	e1.printStackTrace();
}

Solution 5 - Java

I wrote this function:

public static String encode(@NonNull String uriString) {
	if (TextUtils.isEmpty(uriString)) {
		Assert.fail("Uri string cannot be empty!");
		return uriString;
	}
	// getQueryParameterNames is not exist then cannot iterate on queries
	if (Build.VERSION.SDK_INT < 11) {
		return uriString;
	}

	// Check if uri has valid characters
	// See https://tools.ietf.org/html/rfc3986
	Pattern allowedUrlCharacters = Pattern.compile("([A-Za-z0-9_.~:/?\\#\\[\\]@!$&'()*+,;" +
			"=-]|%[0-9a-fA-F]{2})+");
	Matcher matcher = allowedUrlCharacters.matcher(uriString);
	String validUri = null;
	if (matcher.find()) {
		validUri = matcher.group();
	}
	if (TextUtils.isEmpty(validUri) || uriString.length() == validUri.length()) {
		return uriString;
	}

	// The uriString is not encoded. Then recreate the uri and encode it this time
	Uri uri = Uri.parse(uriString);
	Uri.Builder uriBuilder = new Uri.Builder()
			.scheme(uri.getScheme())
			.authority(uri.getAuthority());
	for (String path : uri.getPathSegments()) {
		uriBuilder.appendPath(path);
	}
	for (String key : uri.getQueryParameterNames()) {
		uriBuilder.appendQueryParameter(key, uri.getQueryParameter(key));
	}
	String correctUrl = uriBuilder.build().toString();
	return correctUrl;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwhlkView Question on Stackoverflow
Solution 1 - JavaBalusCView Answer on Stackoverflow
Solution 2 - JavaBozhoView Answer on Stackoverflow
Solution 3 - JavaPhileo99View Answer on Stackoverflow
Solution 4 - Javasiddmuk2005View Answer on Stackoverflow
Solution 5 - JavahadilqView Answer on Stackoverflow