URL encoding in Android - 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.

You don't encode the entire URL, only parts of it that come from "unreliable sources".
Java:
String query = URLEncoder.encode("apples oranges", Charsets.UTF_8.name());
String url = "http://stackoverflow.com/search?q=" + query;
Kotlin:
val query: String = URLEncoder.encode("apples oranges", Charsets.UTF_8.name())
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();

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.

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);

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

try {
query = URLEncoder.encode(query, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

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.

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;

Related

URI Builder result has an unexpected colon in it (Android Programming)

For Uri.Builder, I'm using scheme(String) and building a URL string from there. However, within my final String there is a colon symbol : which changes the results from the query. Here is my code.
Uri.Builder toBuild = new Uri.Builder();
final String baseURL = "http://api.openweathermap.org/data/2.5/forecast/daily";
toBuild.scheme(baseURL)
.appendQueryParameter("zip", postal_Code[0])
.appendQueryParameter("mode", "json")
.appendQueryParameter("units", "metric")
.appendQueryParameter("cnt", "7");
String formURL = toBuild.toString();
Log.v(LOG_TAG, "Formed URL: " + formURL);
My resulting String should have been http://api.openweathermap.org/data/2.5/forecast/daily?zip=94043&mode=json&units=metric&cnt=7
but instead ended like http://api.openweathermap.org/data/2.5/forecast/daily:?zip=94043&mode=json&units=metric&cnt=7
with the colon appearing after the daily from the baseURL String. Please advise on how to remove the colon from the String. Thanks.
The ":" is coming because you are setting the baseUrl using the scheme which is supposed to be ("http", "https" etc) and in a url scheme is always followed by a colon so that is why u see the extra colon.
I would build this URL part by part like this:
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
.authority("api.openweathermap.org")
.appendPath("data")
.appendPath("2.5")
.appendPath("forecast")
.appendPath("daily")
.appendQueryParameter("zip", "94043")
.appendQueryParameter("mode", "json")
.appendQueryParameter("units", "metric")
.appendQueryParameter("cnt", "7");
String formURL = builder.toString();
result: http://api.openweathermap.org/data/2.5/forecast/daily?zip=94043&mode=json&units=metric&cnt=7

google calculator results for android

I am making an android application which requires to send a mathematical question like 1+1 to google's calculator and I need to get that result which is displayed on the web. How can I achieve this on android?
One possibility is to create a URL for the equation you are trying to calculate and then use a URLConnection to open the URL and read the webpage source code to find the answer to the equation.
For example if you have the equation:
2+2
Then the URL to calculate the result with the Google Chrome calculator would be:
https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=2%2B2
You will have to construct the proper query in the URL for the equation you are solving. In this URL the query at the end has the equation 2+2:
q=2%2B2 (where the %2B represents the + sign)
After constructing the URL open it with a URLConnection and read the source. The answer to the equation will be in this element:
<span class="cwcot" id="cwos">4</span>
So you can parse the source in order to find that particular span element and retrieve the result of your equation.
This is probably more work than you expected but it is the only solution I can think of to accomplish what you asked. Also, this approach may be error prone and may break easily. I would consider using a different approach altogether such as launching an intent to use the calculator app on the mobile device (even though this approach has issues as well).
EDIT:
This worked for me (it will output: 2 + 2 = 4):
public static void test() {
try {
String source = getUrlSource();
String span = "<span class=\"nobr\"><h2 class=\"r\" style=\"display:inline;font-size:138%\">";
int length = span.length();
int index = source.indexOf(span) + length;
String equation = source.substring(index, source.indexOf("<", index));
System.out.println( "equation: " + equation);
} catch (IOException e) {
e.printStackTrace();
}
}
private static String getUrlSource() throws IOException {
String url = "https://www.google.com/search";
String charset = "UTF-8";
String param1 = "2+2";
String query = String.format("?q=%s", URLEncoder.encode(param1, charset));
HttpsURLConnection urlConn = (HttpsURLConnection)new URL(url + query).openConnection();
urlConn.setRequestProperty("User-Agent", "Mozilla/5.0");
urlConn.setRequestProperty("Accept-Charset", charset);
BufferedReader in = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String inputLine;
StringBuilder a = new StringBuilder();
while ((inputLine = in.readLine()) != null)
a.append(inputLine);
in.close();
return a.toString();
}

Wierd results while trying to build an URI for HTTPGET

I'm trying to build an URL by adding some parameters to my BASEURL:
The problem is the parameters are added to my BASEURL in disorder, and characters as é are replaced by weird stuffs like %C3%A9
String BASEURI="myBaseUri";
void getParameters()
{
HashMap<String, String> map=new HashMap<String, String>();
final String login = ((EditText)alertDialogRegister.findViewById(R.id.regLogin)).getText().toString();
final String password= ((EditText)alertDialogRegister.findViewById(R.id.regPassword)).getText().toString();
final String passwordConfirm= ((EditText)alertDialogRegister.findViewById(R.id.regPasswordConfirm)).getText().toString();
final String firstName= ((EditText)alertDialogRegister.findViewById(R.id.regPrenom)).getText().toString();
final String lastName= ((EditText)alertDialogRegister.findViewById(R.id.regNom)).getText().toString();
final String sexe=((RadioButton)alertDialogRegister.findViewById(((RadioGroup)alertDialogRegister.findViewById(R.id.regSexe)).getCheckedRadioButtonId())).getText().toString();
final String email= ((EditText)alertDialogRegister.findViewById(R.id.regEmail)).getText().toString();
final String telephone= ((EditText)alertDialogRegister.findViewById(R.id.regPhone)).getText().toString();
final String adresse= ((EditText)alertDialogRegister.findViewById(R.id.regAddress)).getText().toString();
final String civilite=((RadioButton)alertDialogRegister.findViewById(((RadioGroup)alertDialogRegister.findViewById(R.id.regCivilite)).getCheckedRadioButtonId())).getText().toString();
map.put("rquest","addUser");
map.put("login", login);
map.put("password", password);
map.put("firstname", firstName);
map.put("lastname", lastName);
map.put("sex", sexe);
map.put("situation", civilite);
map.put("email", email);
map.put("address", adresse);
registeruser(map);
}
public void registeruser(HashMap<String,String> map)
{
Uri.Builder builder = Uri.parse(BASEURI).buildUpon();
builder.appendPath("api.php");
for(Map.Entry<String, String> entry:map.entrySet())
{
builder.appendQueryParameter(entry.getKey(),entry.getValue());
}
Uri builtUri = builder.build();
Log.i("Hossam", builtUri.toString());
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet(builder.toString());
ResponseHandler<String> handler = new BasicResponseHandler();
String result = null;
try {
result = httpclient.execute(request, handler);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
httpclient.getConnectionManager().shutdown();
String tag = null;
//Log.i("http response", result);
}
The order issue, is because you are using a Map, and in Java Maps are unordered and unsorted type of collection, unless you use either LinkedHashMap or TreeMap which cost way more in performance than regular List, if you want specific order you must go for List, other way the Map will always return the values in an unordered way, and related to the special characters is because your URL contains them, and by default the URL is coneverted to its encoded version of them since they can only be ASCII, here is the list of the URL Encoded characters... http://www.degraeve.com/reference/urlencoding.php
Your characters é does not belong to ASCII character-set.
URLs can only contains ASCII character-set.
Since URLs often contain characters outside the ASCII set, the URL has to be converted into a valid ASCII format.
URL encoding replaces unsafe ASCII characters with a "%" followed by two hexadecimal digits.
URLs cannot contain spaces. URL encoding normally replaces a space with a + sign.
Source:w3schools

android: parse html from page

i would like to parse out some text from a page.
Is there an easy way to save the product info in to a string for example? Example url: http://upcdata.info/upc/7310870008741
Thanks
Jsoup is excellent at parsing simple HTML from Android applications:
http://jsoup.org/
To get the page, just do this:
URL url = new URL("http://upcdata.info/upc/7310870008741");
Document document = Jsoup.parse(url, 5000);
Then you can parse out whatever you need from the Document. Check out this link for a brief description of how to extract parts of the page:
http://jsoup.org/cookbook/extracting-data/dom-navigation
If you want to read from a URL into a String:
StringBuffer myString = new StringBuffer();
try {
String thisLine;
URL u = new URL("http://www.google.com");
DataInputStream theHTML = new DataInputStream(u.openStream());
while ((thisLine = theHTML.readLine()) != null) {
myString.append(thisLine);
}
} catch (MalformedURLException e) {
} catch (IOException e) {
}
// call toString() on myString to get the contents of the file your URL is
// pointing to.
This will give you a plain old string, HTML markup and all.
String tmpHtml = "<html>a whole bunch of html stuff</html>";
String htmlTextStr = Html.fromHtml(tmpHtml).toString();

how to url encode in android?

I am using grid view for displaying image using xml parsing,i got some exception like
java.lang.IllegalArgumentException: Illegal character in path at
index 80:
http://www.theblacksheeponline.com/party_img/thumbspps/912big_361999096_Flicking
Off Douchebag.jpg
How to solve this problem? I want to display all kind of url,anybody knows please give sample code for me.
Thanks All
URL encoding is done in the same way on android as in Java SE;
try {
String url = "http://www.example.com/?id=123&art=abc";
String encodedurl = URLEncoder.encode(url,"UTF-8");
Log.d("TEST", encodedurl);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
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
As Ben says in his comment, you should not use URLEncoder.encode to full URLs because you will change the semantics of the URL per the following example from the W3C:
The URIs
http://www.w3.org/albert/bertram/marie-claude
and
http://www.w3.org/albert/bertram%2Fmarie-claude
are NOT identical, as in the second
case the encoded slash does not have
hierarchical significance.
Instead, you should encode component parts of a URL independently per the following from RFC 3986 Section 2.4
Under normal circumstances, the only
time when octets within a URI are
percent-encoded is during the process
of producing the URI from its
component parts. This is when an
implementation determines which of the
reserved characters are to be used as
subcomponent delimiters and which can
be safely used as data. Once
produced, a URI is always in its
percent-encoded form.
So, in short, for your case you should encode/escape your filename and then assemble the URL.
You don't encode the entire URL, only parts of it that come from "unreliable sources" like.
String query = URLEncoder.encode("Hare Krishna ", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;
URLEncoder should be used only to encode queries, use java.net.URI class instead:
URI uri = new URI(
"http",
"www.theblacksheeponline.com",
"/party_img/thumbspps/912big_361999096_Flicking Off Douchebag.jpg",
null);
String request = uri.toASCIIString();
you can use below method
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();
}
I tried with URLEncoder that added (+) sign in replace of (" "), but it was not working and getting 404 url not found error.
Then i googled for get better answer and found this and its working awesome.
String urlStr = "http://www.example.com/test/file name.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();
This way of encoding url its very useful because using of URL we can separate url into different part. So, there is no need to perform any string operation.
Then second URI class, 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.
I recently wrote a quick URI encoder for this purpose. It even handles unicode characters.
http://www.dmurph.com/2011/01/java-uri-encoder/

Categories

Resources