I am working on a project with google maps where i try to retrieve bitmaps from URL and save it to internal memory.After downloading the bitmap into internal memory i try to read it from memory using the following code:
public Bitmap getImageBitmap(Context context, String name) {
FileInputStream fis = null;
try {
File myFile = new File (path_file + File.separator + name);
fis = new FileInputStream(myFile);
Bitmap b = BitmapFactory.decodeStream(fis);
return b;
} catch(Exception e) {
return null;
} finally {
if(fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The problem is that the code works fine on Android 2.6 , but it throws Filenotfoundexception at this line
fis = new FileInputStream(myFile);
Why does the code work fine on older versions of android but throws exception on newer versions of android?How do i fix the issue?
EDIT:
The issue was with the code which downloads the bitmap:
The code that i am using is:
public void downloadfile(String path,String filepath)
{
try
{
URL url = new URL(path);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File file = new File(filepath);
file.createNewFile();
FileOutputStream outStream = new FileOutputStream(file);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1)
{
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
The code throws NetworkonMainThreadException at this line: InputStream is = ucon.getInputStream();
This error is thrown only on the newer android version.Please help!!
Try this..
Just use
path_file=MainActivity.this.getFilesDir();
EDIT
class downloadfile extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... urls) {
try
{
URL url = new URL(path);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File file = new File(filepath);
file.createNewFile();
FileOutputStream outStream = new FileOutputStream(file);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1)
{
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
protected void onPostExecute() {
// TODO: check this.exception
// TODO: do something with the feed
}
}
Instead if calling downloadfile method use below
new downloadfile().execute();
You are trying to perform a network related operation in Main thread,you are getting this NetworkonMainThreadException.
Refer to my answer here for more explanation.
In your case try downloading the bitmap file in worker thread. You can use an Asynctask for it and download bitmap in doInBackground().
Refer this example
Related
I'm trying to download the following the following file, with this link that redirects you to a direct download: http://www.lavozdegalicia.es/sitemap_sections.xml.gz
I've done my own research, but all the results I see are related to HTTP URL redirections
[3xx] and not to direct download redirections (maybe I'm using the wrong terms to do the research).
I've tried the following pieces of code (cite: https://programmerclick.com/article/7719159084/ ):
// Using Java IO
private static void downloadFileFromUrlWithJavaIO(String fileName, String fileUrl) {
BufferedInputStream inputStream = null;
FileOutputStream outputStream = null;
try {
URL url = new URL(fileUrl);
inputStream = new BufferedInputStream(url.openStream());
outputStream = new FileOutputStream(fileName);
byte data[] = new byte[1024];
int count;
while ((count = inputStream.read(data, 0, 1024)) != -1) {
outputStream.write(data, 0, count);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Using Apache common IO
private static void downloadFileFromUrlWithCommonsIO(String fileName, String fileUrl) {
try {
FileUtils.copyURLToFile(new URL(fileUrl), new File(fileName));
} catch (IOException e) {
e.printStackTrace();
}
}
// Using NIO
private static void downloadFileFromURLUsingNIO(String fileName, String fileUrl) {
try {
URL url = new URL(fileUrl);
ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
fileOutputStream.close();
readableByteChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
But the result I get with any of the three options is an empty file, my thoughts are that the problem is related to the file being a .xml.gz because when I debug it the inputStream doesn't seem to have any content.
I ran out of options, anyone has an idea of how to handle this case, or what would be the correct terms I should use to research about this specific case?
I found a solution, there's probably a more polite way of achieving the same result but this worked fine for me:
//Download the file and decompress it
filecount=0;
URL compressedSitemap = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) compressedSitemap.openConnection();
con.setRequestMethod("GET");
if (con.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP || con.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM) {
String location = con.getHeaderField("Location");
URL newUrl = new URL(location);
con = (HttpURLConnection) newUrl.openConnection();
}
String file = "/home/user/Documentos/Decompression/decompressed" + filecount + ".xml";
GZIPInputStream gzipInputStream = new GZIPInputStream(con.getInputStream());
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = gzipInputStream.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
filecount++;
Two things to note:
When I was trying to do HTTPGet the url that was a redirect, the response code was 301 or 302 (depending on the example I used), I overcame this problem with the if check, that follows the redirect and aims to the downloaded file.
Once aiming the file, to get the content of the compressed file I found the GZIPInputStream package, that allowed me to get an inputStream directly from the compressed file and dump it on an xml file, that saved me the time of doing it on three steps (decompress, read, copy).
I'm receiving URL of images and other data from API and showing images into recyclerview, I want to store images in room database in a byte array format, but I'm getting an error while converting image URL to a byte array. My app is crashing at url.openstream();.
private byte[] getByteArrayImage(String imageUrl) {
URL url = null;
try {
url = new URL(imageUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
byte[] chunk = new byte[4096];
int bytesRead;
InputStream stream = url.openStream();
while ((bytesRead = stream.read(chunk)) > 0) {
outputStream.write(chunk, 0, bytesRead);
}
url.openStream().close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return outputStream.toByteArray();
}
There are a couple of problems with your code:
As already noted in a comment, you call openStream() twice.
If an exception occurs, close() won't be called in your code. Use try-with-resources instead.
Propagate exceptions to the caller. The caller will generally want to know the exception message.
Don't ever use printStackTrace(). This is the worst way to report errors.
After the first printStackTrace(), you continue with a null URI, which will cause a NullPointerException.
The method should be static.
Here's how I would write this:
private static byte[] getImageBytes(String imageUrl) throws IOException
{
URL url = new URL(imageUrl);
ByteArrayOutputStream output = new ByteArrayOutputStream();
try (InputStream stream = url.openStream())
{
byte[] buffer = new byte[4096];
while (true)
{
int bytesRead = stream.read(buffer);
if (bytesRead < 0) { break; }
output.write(buffer, 0, bytesRead);
}
}
return output.toByteArray();
}
I recommend below pseudo code to read data from URL:
Thread t = new Thread(new Runnable()
{
#Override
public void run()
{
try
{
URL url = new URL("you'r address");
URLConnection connection = url.openConnection();
InputStream is = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
StringBuffer sb = new StringBuffer();
int r;
while((r = isr.read()) != -1)
{
sb.append(r);
}
byte buffer[] = sb.toString().getBytes();
}
catch (MalformedURLException e)
{
e.printStackTrace();
Log.i("tag" , "MalformedURLException"+e.getMessage());
}
catch (IOException e)
{
e.printStackTrace();
Log.i("tag" , "IOException"+e.getMessage());
}
}
});
t.start();
I am developing an android project with google maps and it has custom images for the markers of google map.But instead of downloading the images each time, the first time the marker images are downloaded into internal memory, from the second time onwards i check if the images are downloaded and then they are retrieved from memory.
But the code works fine on my phone (Android version 2.6.3) , But when i tried on newer devices (Android 4 and above) the code for retrieving the downloaded bitmap image returns null.
The code for checking if the images have been downloaded:
public void checkcategoryimagesavailable() {
path_file=MainActivity.this.getFilesDir().getAbsolutePath();
for(int i=0;i<catprearr.size();i++) {
File file = new File(path_file+File.separator+catprearr.get(i)+".png");
if(file.exists()) {
} else {
downloadfile(URL_image+catprearr.get(i)+".png",path_file+File.separator+catprearr.get(i)+".png");
}
}
setvaluesonmap();
}
The code for downloading the images:
public void downloadfile(String path,String filepath) {
try {
URL url = new URL(path);
URLConnection ucon = url.openConnection();
ucon.setReadTimeout(5000);
ucon.setConnectTimeout(10000);
InputStream is = ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
File file = new File(filepath);
file.createNewFile();
FileOutputStream outStream = new FileOutputStream(file);
byte[] buff = new byte[5 * 1024];
int len;
while ((len = inStream.read(buff)) != -1) {
outStream.write(buff, 0, len);
}
outStream.flush();
outStream.close();
inStream.close();
} catch(Exception e) {
e.printStackTrace();
}
}
The code for setting the markers:
public void setvaluesonmap() {
for(int i=0;i<list.size();i++) {
final Store_data s=list.get(i);
Bitmap obj=getImageBitmap(MainActivity.this,s.category+".png");
obj=Bitmap.createScaledBitmap(obj,68,62,false);
iv_category_logo.setImageBitmap(obj);
googleMap.addMarker(new MarkerOptions().title(s.store_name)
.icon(BitmapDescriptorFactory.fromBitmap(createDrawableFromView(MainActivity.this, custom_layout)))
.position(new LatLng(Double.parseDouble(s.store_latitude),Double.parseDouble(s.store_longitude))));
}
}
The code for retrieving the downloaded image:This is the troubled code:the bitmap returns null on newer devices
public Bitmap getImageBitmap(Context context,String name) {
try {
// FileInputStream fis = context.openFileInput(name);
// File file = new File("filesdir", name);
File myFile = new File (path_file+File.separator+name);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
Bitmap b = BitmapFactory.decodeStream(fis);
//fis.close();
return b;
} catch(Exception e) {
return null;
}
}
Why does it work fine on older devices,But doesnt work on newer devices.
I have a url of a file which works perfectly in browser and Java SE application but it gives me 403 forbidden error in servlet. Following are the codes of both Java SE program and the servlet
Java SE code
public class UrlDownload {
final static int size=1024;
public static void fileUrl(){
OutputStream outStream = null;
URLConnection uCon = null;
InputStream is = null;
try{
URL Url;
byte[] buf;
int ByteRead,ByteWritten=0;
Url= new URL("http://o-o---preferred---bharti-del2---v17--- lscache7.c.youtube.com/videoplayback?upn=6BFud0UQ_-0&sparams=cp%2Cgcr%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&fexp=900147%2C907217%2C922401%2C919804%2C920704%2C912806%2C906831%2C911406%2C913550%2C912706&key=yt1&itag=37&ipbits=8&signature=6EBF4572274A427AFF58E023CEC8B62439E0B914.BD6827306B81393BE3998FA0F0701E6F2701A3F8&mv=m&sver=3&mt=1345685891&ratebypass=yes&source=youtube&ms=au&gcr=in&expire=1345708167&ip=116.203.237.173&cp=U0hTSldLVl9LUUNOM19PRVpCOkV6WE5pcUF1NjQ5&id=9d8c9310d90eae67&quality=hd1080&fallback_host=tc.v17.cache7.c.youtube.com&type=video/mp4");
outStream = new BufferedOutputStream(new
FileOutputStream("video"));
uCon = Url.openConnection();
is = uCon.getInputStream();
buf = new byte[size];
while ((ByteRead = is.read(buf)) != -1)
{
System.out.println("Downloading file");
outStream.write(buf, 0, ByteRead);
ByteWritten += ByteRead;
}
System.out.println("Downloaded Successfully.");
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
is.close();
outStream.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
Servlet Code
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("video/mp4");
String url=request.getParameter("url");
URLConnection con = null;
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
InputStream in=null;
byte[] buffer;
int ByteRead,ByteWritten=0;
try {
URL dUrl=new URL(url);
con=dUrl.openConnection();
in=con.getInputStream();
buffer = new byte[1024];
while ((ByteRead = in.read(buffer)) != -1)
{
System.out.println("Downloading file");
out.write(buffer, 0, ByteRead);
ByteWritten += ByteRead;
}
} finally {
out.close();
in.close();
}
}
url is the same url given as a parameter to this servlet
YouTube download URLs are intended for one-time use only -- they are bound to the IP range that they were initially generated for, and expire after some time. Hard-coding one in your application, as you've done here, will lead to inevitable failure.
I have this method that downloads .csv files from yahoo finance and saves them locally. It is accessed during a loop so it is downloading many files from a list. However sometimes a symbol is entered incorrectly, no longer exists, or the connection times out. How can I amend this method so that connection time outs are retried and incorrect symbols (meaning the url does not work) are just skipped over without ending the program?
public static void get_file(String symbol){
OutputStream outStream = null;
URLConnection uCon = null;
InputStream is = null;
String finance_url = "http://ichart.finance.yahoo.com/table.csv?s="+symbol;
String destination = "C:/"+symbol+"_table.csv";
try {
URL Url;
byte[] buf;
int ByteRead,ByteWritten=0;
Url= new URL(finance_url);
outStream = new BufferedOutputStream(new FileOutputStream(destination));
uCon = Url.openConnection();
is = uCon.getInputStream();
buf = new byte[size];
while ((ByteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, ByteRead);
ByteWritten += ByteRead;
}
}catch (Exception e) {
System.out.println("Error while downloading "+symbol);
e.printStackTrace();
}finally {
try {
is.close();
outStream.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
Why not call the method again when an exception is thrown. You can narrow down the exception type to indicate when a retry should be initiated.
public static void get_file(String symbol){
OutputStream outStream = null;
URLConnection uCon = null;
InputStream is = null;
String finance_url = "http://ichart.finance.yahoo.com/table.csv?s="+symbol;
String destination = "C:/"+symbol+"_table.csv";
try {
URL Url;
byte[] buf;
int ByteRead,ByteWritten=0;
Url= new URL(finance_url);
outStream = new BufferedOutputStream(new FileOutputStream(destination));
uCon = Url.openConnection();
is = uCon.getInputStream();
buf = new byte[size];
while ((ByteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, ByteRead);
ByteWritten += ByteRead;
}
}catch (Exception e) {
getFile(symbol);
}finally {
try {
is.close();
outStream.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}