Android Help with adding a progress dialog while image loading? - android

I have been following a tutorial that remotely downloads an image to an imageview, but i'm not sure how to add a progress dialog (image or something) to show the user that image is downloading, instead of just a blank screen.
Hope someone can help
ImageView imView;
String imageUrl="http://domain.com/images/";
Random r= new Random();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,
WindowManager.LayoutParams.FLAG_FULLSCREEN );
setContentView(R.layout.galleryshow);
Button bt3= (Button)findViewById(R.id.get_imagebt);
bt3.setOnClickListener(getImgListener);
imView = (ImageView)findViewById(R.id.imview);
}
View.OnClickListener getImgListener = new View.OnClickListener()
{
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
int i =r.nextInt(114);
downloadFile(imageUrl+"image-"+i+".jpg");
Log.i("im url",imageUrl+"image-"+i+".jpg");
}
};
Bitmap bmImg;
void downloadFile(String fileUrl){
URL myFileUrl =null;
try {
myFileUrl= new URL(fileUrl);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
int length = conn.getContentLength();
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
imView.setImageBitmap(bmImg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

You should look at this : asynctask is the way to go.
Android : Loading an image from the Web with Asynctask
Regards,
Stéphane

You need to look at ProgressBar class and basically use that while the image is loading. Alternatively you could put default image while the image is being downloaded.
To put the progress bar in your code, the easiest basically just flip their visibility in the layout.
In your layout, you have two things. One placeholder for ProgressBar and the other is for the image
The progressbar is set to VISIBLE initially and the image to GONE
After you execute the AsyncTask (see below), you need to flip the visibility. Basically change the progressBar to GONE and the image to VISIBLE
Here is what you should try to do. Check the NOTE and TODO comment in the code. Note: I just modified your code, but haven't run it, but this should be enough to illustrate the idea.
Some key points:
Long running task that might block UI Thread should get executed in AsyncTask. In your case, this would be downloading the image
Post execution that needs to be handled in UI Thread should be handle in postExecute()
Doing e.printStacktrace() during catching Exception is not a good practice. Without appropriate handles, this exception is not being handled correctly and might cause bugs in the future. In addition, during production, this information doesn't help you at all when bugs occur on the client's side since it is merely printing out in the console
View.OnClickListener getImgListener = new View.OnClickListener()
{
#Override
public void onClick(View view) {
// NOTE: here you need to show the progress bar, you could utilize ProgressBar class from Android
// TODO: Show progress bar
AsyncTask asyncTask = new AsyncTask() {
#Override
public Bitmap doInBackground(Void... params) {
int i =r.nextInt(114);
// NOTE: move image download to async task
return downloadFile(imageUrl+"image-"+i+".jpg");
}
#Override
public void onPostExecute(Bitmap result) {
// TODO: hide the progress bar here
// and flip the image to VISIBLE as noted above
if(result != null) {
imView.setImageBitmap(result);
} else {
// NOTE 3: handle image null here, maybe by showing default image
}
}
};
// NOTE: execute in the background so you don't block the thread
asyncTask.execute();
}
};
// Change the return type to Bitmap so we could use it in AsyncTask
Bitmap downloadFile(String fileUrl){
URL myFileUrl =null;
try {
myFileUrl= new URL(fileUrl);
} catch (MalformedURLException e) {
// NOTE: You should not have e.printStacktrace() here. In fact
// printStacktrace is a bad practice as it doesn't really do anything
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
int length = conn.getContentLength();
InputStream is = conn.getInputStream();
Bitmap bmImg = BitmapFactory.decodeStream(is);
// return image this to the main Thread
return bmImg;
} catch (IOException e) {
return null;
}
}

Related

How to get specific images from a website and display them in an Android App?

Given the URL of a website I want to retrieve the logo and background image of the website and display it in an android app. For example from this link I would want the background image and the hack western logo.
EDIT: I forgot to mention I am trying to achieve this effect for a list of URL's of undetermined size until run time
Use this AsyncTask for loading image from URL
public class LoadImageTask extends AsyncTask<Void, Void, Void>{
private Bitmap mMyBitmap;
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL("https://hackwestern.com/images/logo_vert_spons.png");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
mMyBitmap = BitmapFactory.decodeStream(input);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mImageView.setImageBitmap(mMyBitmap);
}
}
Then call it on OnCreate or somewhere you need:
new LoadImageTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Set image to downloaded bitmap in a separate class

I am trying to pass an imageview to a non activity class that will handle looking up the image from online and then subsequently set the image. My error that I am receiving is that when trying to set the image, the bitmap is read as null even though it has been received.
my constructor
ImageView iview_image;
public ImageLoader(String url, Context newContext, ItemsDto items, ImageView imageView)
{
try
{
Log.e("IMGURL",url);
str_img=url;
context=newContext;
this.context=newContext;
itemsDto=items;
iview_image=imageView;
iview_image.findViewById(R.id.icon);
}
my async task
protected Void doInBackground(Void... arg0)
{
try
{
Log.e("Async Img Load", "Before the try");
//Sets image status to help other classes know when image is ready
//image lookups
URL url = new URL(str_img);
HttpGet httpRequest = null;
httpRequest = new HttpGet(url.toURI());
//http get
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity b_entity = new BufferedHttpEntity(entity);
InputStream input = b_entity.getContent();
bm_productImage = BitmapFactory.decodeStream(input);
setBm_productImage(bm_productImage);
str_imgStatus="Image recieved";
}
catch (Exception e)
{
Log.e("IMG_ERROR",e.toString());
}
try{iview_image.setImageBitmap(getBm_productImage());}
catch(Exception e){ Log.e("more errors wheee", e.toString());}
doPendingActivity();
return null;
}
#Override
protected void onPostExecute(Void result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
try
{
}
catch(Exception e)
{
Log.e("Post_ERROR", e.toString());
}
}
I've been where you are, and I'll give you a recommendation. However, first, I'll answer your question. The way I downloaded a stream from a URL and saved it into a Bitmap was:
try {
URL url_obj = new URL(url);
Bitmap imageToReturn = BitmapFactory.decodeStream(url_obj.openConnection().getInputStream());
return imageToReturn; // or do whatever you want
} catch (MalformedURLException e) {
return null;
} catch (SocketTimeoutException e) {
return null;
} catch (IOException e) {
return null;
}
However, this solution is far from ideal when dealing with a lot of images. Android does not handle Bitmaps in memory well, and after you allocate a lot of Bitmaps in memory, it's a matter of time before you get an OutOfMemoryError exception thrown in your face.
I'd recommend using an image downloading/caching library like Picasso (http://square.github.io/picasso/). You can download the JAR file and include it in your project (it's really just that simple!). The default usage scenario is:
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
but that's not the only possibility. If you want to save the bitmap or do something else with it, you can do:
Picasso.with(context).load(url).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
// do what you want to do with the bitmap
// if it has already been downloaded, it will be loaded from
// cache (memory or disk). The loaded bitmap is in the parameter
}
#Override
public void onBitmapFailed(Drawable drawable) {
// whatever you want to do if if could not load the image
}
#Override
public void onPrepareLoad(Drawable drawable) {
// do whatever you want to do right before your request is submitted
}
});
Any of the methods can be empty if you want, use it as needed (all of the methods need to be there though, or the interface implementation will give you a compilation error).
I think you'll find this solution to be better and it will save you headaches in the future when you start to run out of memory. I hope it was useful!

Loading image in ImageView from OpenLibrary API

I have written the below program in AsyncTask to load image from internet and show in ImageView. The program works fine if I give any direct image link, but don't work with API links.
What I mean is, for example, to have the cover of Farmer Boy from OpenLibrary, I need to give below source in html or in browser:
http://covers.openlibrary.org/b/isbn/9780385533225-S.jpg
However, if I enter above link in browser, the browser redirect to below address.
http://ia700804.us.archive.org/zipview.php?zip=/12/items/olcovers4/olcovers4-M.zip&file=49855-M.jpg
My problem is, my code works with last one, but not with the first one.
How can I get the image (in my android application) using the first link?
CODE:
private class getImageOpenLibrary extends AsyncTask<String, Void, Bitmap>
{
protected Bitmap doInBackground(String... args) {
URL newurl = null;
try {
//newurl = new URL("http://covers.openlibrary.org/b/isbn/"+args[0]+"-M.jpg"); // THIS DOES NOT WORK, args[0] = 9780064400039
newurl = new URL("http://ia700804.us.archive.org/zipview.php?zip=/12/items/olcovers4/olcovers4-M.zip&file=49855-M.jpg"); //THIS WORKS
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap mIcon_val = null;
try {
mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mIcon_val;
}
//#Override
protected void onPostExecute(Bitmap result1)
{
ImageView mImageView = (ImageView) findViewById(R.id.cover);
mImageView.setImageBitmap(result1);
}
}
You should handle the redirection. The url redirects to another URL. You should open a second connection on the redirect URL. To be able to get the redirect URL, set setInstanceFollowRedirects to false on the connection and read the Location in the header fields.
URL url = new URL("http://covers.openlibrary.org/b/isbn/9780385533225-S.jpg");
HttpURLConnection firstConn = (HttpURLConnection) url.openConnection();
firstConn.setInstanceFollowRedirects(false);
URL redirectURL = new URL(firstConn.getHeaderField("Location"));
URLConnection redirectConn = redirectURL.openConnection();
Bitmap bitmap = BitmapFactory.decodeStream(redirectConn.getInputStream());

Android - Grabbing an image from a URL and displaying it in an ImageView with an AsyncTask

I'm trying to get the app to show an image from a URL, im fairly certain the issue is with the AsyncTask but I've returned to this code several times over the past week and I still cant see where I'm going wrong.
The Internet permission is set and I am getting no LogCat
ImageView eventImage2;
eventImage2 = (ImageView) findViewById(R.id.eventImage2);
new imageupdate().execute();
public class imageupdate extends AsyncTask<Bitmap, Void, Bitmap> {
#Override
protected Bitmap doInBackground(Bitmap... url) {
URL url1;
try {
url1 = new URL("http://masterzangetsu.eu/Apps/NowIGetYou/banner.png");
HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return img;
}
protected void onPreExecute(String result) {
}
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
eventImage2.setImageBitmap(result);
}
}
As far as I can tell the img variable defined with the
img = BitmapFactory.decodeStream(is);
isnt being linked to the variable being returned
return img;
Both variables result and img are coming back as null
Change this
Bitmap result = null;
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is);
img = result;
to
Bitmap img = null;
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is);
result = img;
and return result in doInBackground(). You have them switched around so 'img' will be null no matter what happens.
Also, you can't use Toast in doInBackground() as this method isn't run on the UI thread. You will need to make that a Log or put your Toast in onPostExecute() or onProgressUpdate(). These are the things I see. If you are still having problems then you need to be a little more clear on what specifically. You will need to debug and use breakpoints to see what isn't being returned that should be and pinpoint a little more what the problem is
AsyncTask - any UI updates must be done in one of the other methods of AsyncTask other than doInBackground() or you can pass a value back to the Activity to update the UI there.

Fetch and display image on click of a button

I want to fetch an image on click of a button and display it in the same activity. This is what i have tried
public class MainActivity extends Activity {
ImageView imView;
String imageUrl="http://variable3.com/files/images/email-sig.jpg";
Random r= new Random();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Button bt3= (Button)findViewById(R.id.get_imagebt);
bt3.setOnClickListener(getImgListener);
imView = (ImageView)findViewById(R.id.imview);
Log.i("img already downloaded","img");
}
View.OnClickListener getImgListener = new View.OnClickListener()
{
public void onClick(View view) {
// TODO Auto-generated method stub
//i tried to randomize the file download, in my server i put 4 files with name like
//png0.png, png1.png, png2.png so different file is downloaded in button press
int i =r.nextInt(4);
downloadFile(imageUrl);
Log.i("im url",imageUrl);
}
};
Bitmap bmImg;
void downloadFile(String fileUrl){
URL myFileUrl =null;
try {
myFileUrl= new URL(fileUrl);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
int length = conn.getContentLength();
InputStream is = conn.getInputStream();
Log.i("im connected","Download");
bmImg = BitmapFactory.decodeStream(is);
imView.setImageBitmap(bmImg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Didn't understand your question, but if it's about that comment about randomizing the download, then just add your i variable to the downloadFile() method parameters:
void downloadFile(String fileUrl, int i)
Then add a switch block to the method's body and make it download the file you need for a current value of i. Hope this is what you needed.

Categories

Resources