Bad URL encoding for images - java

In my app, there is an ImageView that display an image from a URL.
I download the image using this method:
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
return bitmap;
This works only with URLs that has numbers or english letters and doesn't work with any other chars (like spaces):
Good URL: http://site.com/images/image.png
Bad URL: http://site.com/images/image 1.png
I tried to chage the URL encoding (URLEncoder.encode), but it changes the whole URL (incliding slashes, ect...).
Do I need to replace some chars after the encoding? or maybe there is a better way?
Thanks :)

"Url encoding in Android"
You don't encode the entire URL, only parts of it that come from
"unreliable sources". -yanchenko
String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "https://stackoverflow.com/search?q=" + query;
This is fine if 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. – Craig
B
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();

Related

How do I save a large file from a URL to the local

I have tried this below code which is working fine with the small size files.
URL url = new URL(downloadLink);
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
FileOutputStream fos = new FileOutputStream(newFile);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
If the file is a large file, it is giving an error like :
java.io.IOException:Server returned HTTP response code: 400 for URL:https://dl.dropboxusercontent.com/1/view/79q8i6f9zqx7y2w/Paragliding in Himalayas.avi
Can anyone help me.
The URL you're trying to download is invalid. URLs can't contain spaces. You need to URL encode it:
https://dl.dropboxusercontent.com/1/view/79q8i6f9zqx7y2w/Paragliding%20in%20Himalayas.avi
Have a look at: how do I encode a complete http url String correctly?, for an approach to encoding the URL. Unfortunately, just using URLEncoder.encode() won't cut it, since it encodes slashes, etc.
You can hand this task over to Os itself by using DownloadManager
private fun startDownload(url: String) {
val request = DownloadManager.Request(Uri.parse(url))
request.allowScanningByMediaScanner()
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, url.substring(url.lastIndexOf("/")))
val dm = activity!!.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
dm.enqueue(request)
Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show()
}

URL wont open file:\C filepath in Java

I need to open a filename using a URL(java.net.URL) as below:
file:/C:/RAdev/Basic/src/test/resources/xml Data/test
dir/app-config-seed-data.xml
I've the following java code to read
fileURL = new File(filePath).toURI().toURL();
is = fileURL.openStream();
Since windows can access file:\, even URL should be able to open the same.
Workaround used for now:
public static final String FILE_URL_PREFIX = "file:";
if (filePath.contains(FILE_URL_PREFIX)) {
filePath = filePath.replaceAll("file:/", "");
System.out.println("Modified filepath - " + filePath);
}
fileURL = new File(filePath).toURI().toURL();
is = fileURL.openStream();
Is the above workaround needed, please let me know if there is another way to reap the benefits of URL accessing. I'm new to URL/URI in java, help is really appreciated.
Thanks.
file:/C:/ is not a valid file url. Try starting your URLs with file://C:/.
Additionally, the File(String) constructor does not take a URL, it takes a local file path. If you have a URL as a string that you want to parse, use the URL(String) constructor:
URL fileURL = new URL("file://C:/RAdev/Basic/src/test/resources/xml Data/test dir/app-config-seed-data.xml");
is = fileURL.openStream();
Adding the below implementation on top of Darth Android suggestion worked:
URL url = new URL(filePath);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(),
url.getPort(), url.getPath(), url.getQuery(),
url.getRef());
URL fileURL = uri.toURL();
InputStream is = fileURL.openStream();

Building a JSON search parser

I am working with a database api and they give me the opportunity to search using a url through their database.
This is the url =
http://api.database.com/v2/search?q=(THE PRODCUT)&type=(THE TYPE OF PRODUCT)
&key=(myApiKey)
I want to make a simple search bar were the user can type the product name and choose a type (catagorie) to insert that into the url and then look the product up in the database.
I know how I can parse the data from the url but how can I insert the users text into the url to change it ?
It's always a better approach to use URI to build your search url.
Try something like this
final String FORECAST_BASE_URL ="http://api.openweathermap.org/data/2.5/forecast/daily?";
final String QUERY_PARAM = "q";
Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon()
.appendQueryParameter(QUERY_PARAM, params[0])
.build();
URL url = new URL(builtUri.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
And then read the response from the inputStream.
InputStream inputStream = urlConnection.getInputStream();
You can use string concatenation or you can use String.format(String format, Object... args). For example:
String url = String.format("http://api.database.com/v2/search?q=%s&type=%s&key=%", product, productType, apiKey);
or :
var product = "Product";
var productType="ProductType";
var url = "http://api.database.com/v2/search?q="+product+"&type="+productType+"&key="+myApiKey;

How to escape a string in Android?

I can not find an answer to that and I do not know how to compile org.apache.commons.lang.StringEscapeUtils, which is the only solution I found on the internet.
Also, I do not understand why I can not do something like this
s = s.replaceAll(" ","\\ ");
I think you can use
URLEncoder.encode("your URL here", "UTF8")
Use this:
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();
Source: Url encoding in Android
This should be the correct answer in that post.

Java - how to encode URL path for non Latin characters

Currently there is final URL url = new URL(urlString); but I run into server not supporting non-ASCII in path.
Using Java (Android) I need to encode URL from
http://acmeserver.com/download/agc/fcms/儿子去哪儿/儿子去哪儿.png
to
http://acmeserver.com/download/agc/fcms/%E5%84%BF%E5%AD%90%E5%8E%BB%E5%93%AA%E5%84%BF/%E5%84%BF%E5%AD%90%E5%8E%BB%E5%93%AA%E5%84%BF.png
just like browsers do.
I checked URLEncoder.encode(s, "UTF-8"); but it also encodes / slashes
http%3A%2F%2acmeserver.com%2Fdownload%2Fagc%2Ffcms%2F%E5%84%BF%E5%AD%90%E5%8E%BB%E5%93%AA%E5%84%BF%2F%E5%84%BF%E5%AD%90%E5%8E%BB%E5%93%AA%E5%84%BF.png
Is there way to do it simply without parsing string that the method gets?
from http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
B.2.1 Non-ASCII characters in URI attribute values Although URIs do
not contain non-ASCII values (see [URI], section 2.1) authors
sometimes specify them in attribute values expecting URIs (i.e.,
defined with %URI; in the DTD). For instance, the following href value
is illegal:
...
We recommend that user agents adopt the following convention for
handling non-ASCII characters in such cases:
Represent each character in UTF-8 (see [RFC2279]) as one or more
bytes.
Escape these bytes with the URI escaping mechanism (i.e., by
converting each byte to %HH, where HH is the hexadecimal notation of
the byte value).
You should just encode the special characters and the parse them together. If you tried to encode the entire URI then you'd run into problems.
Stick with:
String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;
Check out this great guide on URL encoding.
That being said, a little bit of searching suggests that there may be other ways to do what you want:
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 will need to have those spaces encoded so you 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.
final URL url = new URL( new URI(urlString).toASCIIString() );
worked for me.
I did it as below, which is cumbersome
//was: final URL url = new URL(urlString);
String asciiString;
try {
asciiString = new URL(urlString).toURI().toASCIIString();
} catch (URISyntaxException e1) {
Log.e(TAG, "Error new URL(urlString).toURI().toASCIIString() " + urlString + " : " + e1);
return null;
}
Log.v(TAG, urlString+" -> "+ asciiString );
final URL url = new URL(asciiString);
url is later used in
connection = (HttpURLConnection) url.openConnection();

Categories