Downloading an image in android - java

I have make an application in which I require to download an image from a given link . Its showing no errors an no error messages in logcat. Following is my code
public Drawable getImage(String ImagePath,String fileName) {
Log.v("download", "image downloading from net");
boolean bin = getBinaryWebFile(ImagePath,fileName);
Drawable draw = Drawable.createFromPath(SavePath+fileName); //..........(1)
return draw;
}//getImage ends here*/
private boolean getBinaryWebFile(String inURL, String filename) {
File file = new File(SavePath,filename);
try {
URL url = new URL(inURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("GET");
con.setDoOutput(true);
con.connect();
InputStream is = con.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
byte[] data =new byte[1024];
int x = 0;
while((x=is.read(data,0,1024))>=0){
bout.write(data,0,x);
}
fos.flush();
bout.flush();
fos.close();
bout.close();
is.close();
return true;
} catch (MalformedURLException e) {
Log.d("PowerSaver","getBinaryWebFile->MalformedURLException: "+e.getMessage());
//e.printStackTrace();
} catch (IOException e) {
Log.d("PowerSaver","getBinaryWebFile->I/O exception: "+e.getMessage());
}
return false;
}//getbinarywebfile ends here
On debugging everything is running fine and at last I am getting draw as null (commented as 1) . I have even written the following permmission in manifest .
<uses-permission
android:name = "android.permission.INTERNET"/>
<uses-permission
android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android:name = "android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name = "android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission
android:name = "android.permission.READ_PHONE_STATE"/>
still getting null in draw which is referenced as comment 1.

This code works for me:
private static long DownloadFromUrl(Context context, URL fileUrl,
String fileName) throws Exception { // this is the downloader method
try {
URL myFileUrl = null;
myFileUrl = fileUrl;
// *** Internet connection
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
// int length = conn.getContentLength();
// int[] bitmapData =new int[length];
// byte[] bitmapData2 =new byte[length];
InputStream is = conn.getInputStream();
// decodificar la imagen de internet en bmImg
Bitmap bmImg = BitmapFactory.decodeStream(is);
// ***Save in the the SD
FileOutputStream out = new FileOutputStream(
<path + filename>);
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) > 0) {
out.write(buffer, 0, len);
tam += len;
}
is.close();
// Save using the selected format and quality
bmImg.compress(Bitmap.CompressFormat.PNG,
<quality>, out);
out.flush();
out.close();
// tam=bmImg.getByteCount();
bmImg.recycle();
return tam;
} catch (IOException e) {
// showErrorMessage(context, "Error downloading");
e.printStackTrace();
return 0;
}
}

Are you running your app inside the emulator? Make sure it has a proper internet connection. Sometimes the emulator can loose internet connectivtiy, especially when you're changing networks without restarting the emulator.

Related

Download File from Direct Download URL

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

Download Image from Url and covert into byte array - android

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

Android: simplest url download without progress bar

I have tried to implement over 10-15 different download mechanisms for android java, I have not been able to succeed at all.
I don't care about progress bars or background processes.
I just want one functional download code in fewest lines possible
and I want it to download a binary file (foreground) to the directory in the device wherever it can be accessed as
File pf = new File("filename");
if (pf.exists()) { ... }
Try this (modified from here):
try {
URL url = new URL("http://url.com");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
//THIS IS WHERE YOU GET THE DIRECTORY TO SAVE TO
File SDCardRoot = Environment.getExternalStorageDirectory();
//THIS IS WHERE YOU WILL SET THE FILE NAME
File file = new File(SDCardRoot,"somefile.txt");
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You may also need to add permissions to access the phone directory:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
For information on accessing certain folders on the internal directory, see the android developer page: http://developer.android.com/training/basics/data-storage/files.html#WriteInternalStorage
In fact, the solution on that page is also fairly short:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}

Filenotfoundexception on newer versions of android API Level 4 and later

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

Error handling for URLConnection

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

Categories

Resources