Download image from a url and show in a listview - android

I am fetching title, date and image from an online xml file and storing it in a arraylist. I have taken 3 different arraylists for storing title , date and image.
I am successful in getting image urls , my problem is how to download image from the url and show it in a imageview. The code for fetching the url is below.
if((xpp_name.equals("content")))
{
xpp.next();
strvalue=xpp.getText();
if(strvalue!=null){
String url = strvalue.substring(
strvalue.indexOf("src")+5,, strvalue.indexOf("jpg")+3);
arrayList_for_images.add(url);
}
xpp.next();
xpp.next();}

Start a new thread for downloading image from Url and set image in imageview in handler.
private Bitmap pop_up_image_bitmap ;
private Handler handler ;
private Runnable r;
new Thread(new Runnable() {
#Override
public void run() {
URL newurl;
try {
newurl = new URL(<Url>);
pop_up_image_bitmap = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
handler.post(r);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
Put handler :
handler = new Handler();
r = new Runnable()
{
public void run()
{
if(pop_up_image_bitmap!=null){
imageview.setImageBitmap(pop_up_image_bitmap);
handler.postDelayed(this, 1000);
popUpImageProgressBar.setVisibility(View.INVISIBLE);
}
}
};
handler.postDelayed(r, 1000);

Here you can find a lazy loading library to download images from a URL and show them in a ListView. Also i suggest you to avoid using 3 different Arraylists and use only one ArrayList, instead, with a custom class that is used to store the information of an image(title, date and image url).
EDIT: Here is an example class that holds the information needed for the image:
import java.util.Date;
public class ImageObject {
private String image_name;
private String image_url;
private Date image_date;
public ImageObject() {
}
public ImageObject(String image_name, String image_url, Date image_date) {
this.image_name = image_name;
this.image_url = image_url;
this.image_date = image_date;
}
public void setImageName(String image_name) {
this.image_name = image_name;
}
public void setImageURL(String image_url) {
this.image_url = image_url;
}
public void setImageDate(Date image_date) {
this.image_date = image_date;
}
public String getImageName() {
return this.image_name;
}
public String getImageURL() {
return this.image_url;
}
public Date getImageDate() {
return this.image_date;
}
}
Here is an example usage in witch i initiate a ArrayList with one ImageObject:
ArrayList<ImageObject> data = new ArrayList<ImageObject>();
ImageObject obj = new ImageObject("test.jpg", "www.imageurl.com", new Date());
data.add(obj);
And this is how you retrieve a value from a certain ImageObject object from the ArrayList:
data.get(0).getImageName();

try out this best image loading library ever.
https://github.com/nostra13/Android-Universal-Image-Loader

Related

Avoid using two variables to send variable information to Runnable

I'm trying to send a variable string to Runnable, but find myself having to create two variables for this. One normal string content and one final string finalcontent that is assigned the content of the other string.
String content = "";
try {
content = response.body().string();
} catch (IOException e) {
// Handle exception
}
final String finalcontent = content;
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView text = (TextView)findViewById(R.id.textView);
text.setText(finalcontent);
}
});
Is this the normal way to do this or is there a better way to avoid creating two variables?
it's limitation of Java language design but you should be able to write
final String content;
try {
content = response.body().string();
} catch (IOException e) {
content = "";
// Handle exception
}
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView text = (TextView)findViewById(R.id.textView);
text.setText(content);
}
});
You may create a custom implementation of Runnable, here is an example
void foo(){
String content = "";
try {
content = response.body().string();
} catch (IOException e) {
// Handle exception
}
runOnUiThread(new MyCustomRunnable(content));
}
private class MyCustomRunnable implements Runnable {
private String content;
public MyCustomRunnable(String content) {
this.content = content;
}
#Override
public void run() {
TextView text = (TextView)findViewById(R.id.textView);
if (text != null) {
text.setText(content);
}
}
}
Why don't use RxJava?I think you just want to update UI after you get data from internet.
Observable observable = Observable.create(OnSubscribe()...)
.subscribeOn(Shceduler.io).observeOn(AndroidSchedulers.mainthread)

Get html from list of pages

I have list of web pages(over 100) with I have to vistit and collect data from.
I decided to save the html from all of them to one file, and then use Jsoup to find the interesting data.
But problem is to I do not know how to run 100 threads, and save the responses into one file, any ideas?
maybe it's not a masterpiece, but it works, and I wanted to make it as simple as possible.
ArrayList<String> links = new ArrayList<>();
Elements myDiv;
private void saveDetails() throws IOException {
if(repeat < links.size()){
repeat++;
textView.setText(String.valueOf(repeat));
saveFile(myDiv.toString());
myDiv = null;
getDetails(links.get(repeat));
}else {
textView.setText("finished");
}
}
private void getDetails(String urlStr) {
final String detailsUrl = urlStr;
new Thread() {
#Override
public void run() {
Message msg = Message.obtain();
try {
Document doc = Jsoup.connect(detailsUrl).get();
myDiv = doc.select(".exhibitor-contact");
} catch (IOException e1) {
e1.printStackTrace();
}
detailsHandler.sendMessage(msg);
}
}.start();
}
private Handler detailsHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
try {
saveDetails();
} catch (IOException e) {
e.printStackTrace();
}
}
};
You don't need to save all of them in a file and then process them. You can gather information one by one. It is my suggestion:
arrayList urls = {100 site-url}; //in correct syntax
Document doc = null;
for (String url : urls) {
doc = Jsoup.connect(url).get();
//now proccess doc.toString as you want(in regular expression for example)
//save your desired information
}

Android : How to set image with url by a subroutine

I'm creating a subroutine to get an image using a url. Here is a similar subroutine that I used to parse text from an XML into my UI:
public void loading(int index) {
final Handler handler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
try {
arrayList = XMLPullParser.parse("http://localhost/news.xml", "news", 1, 2, 3);
//URL url = new URL("http://localhost/"+arrayList2.get(1).toString());
//final Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
handler.post(new Runnable() {
public void run() {
chk1.setText(arrayList.get(0).toString());
chk2.setText(arrayList.get(1).toString());
chk3.setText(arrayList.get(2).toString());
try {
img1.setImageBitmap(bitmap("http://localhost/1.jpg"));
img2.setImageBitmap(bitmap("http://localhost/2.jpg"));
img3.setImageBitmap(bitmap("http://localhost/3.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}).start();
}
Here is the change I made to load the images:
static Bitmap bmp;
public Bitmap bitmap(String url_input) throws IOException {
final String get_url = url_input;
new Thread(new Runnable() {
#Override
public void run() {
try {
final URL url = new URL(get_url);
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
return bmp;
}
The subroutine works when parsing text but doesn't work properly when loading the bitmaps. I need to set images to 3 image buttons and want to use a subroutine to do it.
I know it should not use static for my bmp variable, it's just a test to let me know if it works.
Your bitmaps are not displayed because your threading setup is incorrect. Your bitmap method returns before thread it started has finished. Also you are using static variable used by all threads.
I recommend to use AsyncTask and do all your background work there - there is no need to spawn separate threads for every image. Also pay attention to assign values to your checkboxes and images in onPostExecute method because these can be assigned only in main (gui) thread.
You could do it something like this. This asserts that you have the code in an activity. But the thread handling should probably be changes to use an AsyncTask instead.
bitmap(img1, "http://localhost/1.jpg");
.
.
.
public void bitmap(final ImageView imageView, String url_input) throws IOException {
final String get_url = url_input;
new Thread(new Runnable() {
#Override
public void run() {
try {
final URL url = new URL(get_url);
final Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
if (bmp != null) {
runOnUiThread(new Runnable() {
#Override
public void run() {
imageView.setImageBitmap(bmp);
}
});
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}

Change View from other thread

I wrote a code to download an image from internet. And i have to show it in a ImageView which is dynamically created.
And i am getting an error that Only the original thread that created a view hierarchy can touch its views. I know i have to write a handle but how can i do that?
Here is my code:
public class ResimCek implements Runnable {
int resimID = 0;
public ResimCek(int parcaID) {
// store parameter for later user
resimID = parcaID;
}
public void run() {
int resID = getResources().getIdentifier(Integer.toString(resimID) , "tag", getPackageName());
ImageView resim = (ImageView) findViewById(resID);
Drawable image = ImageOperations(getBaseContext(),"http://141.11.11.206/parca/" + Integer.toString(resimID) + ".jpg" ,"I" + Integer.toString(resimID) + ".jpg");
// I AM GETTING ERROR HERE ******************
resim.setImageDrawable(image); // *************************
}
}
private Drawable ImageOperations(Context ctx, String url, String saveFilename) {
try {
InputStream is = (InputStream) this.fetch(url);
Drawable d = Drawable.createFromStream(new URL(url).openConnection().getInputStream(),saveFilename);
return d;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public Object fetch(String address) throws MalformedURLException,IOException {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
private void MalzemeEkle(String malzemeKodu, String malzemeTanimi) {
ImageView parcaresmi = new ImageView(this);
parcaresmi.setId(Integer.parseInt(malzemeKodu));
Runnable r = new ResimCek(Integer.parseInt(malzemeKodu));
new Thread(r).start();
}
public class ResimCek implements Runnable {
int resimID = 0;
public ResimCek(int parcaID) {
// store parameter for later user
resimID = parcaID;
}
public void run() {
int resID = getResources().getIdentifier(Integer.toString(resimID) , "tag", getPackageName());
ImageView resim = (ImageView) findViewById(resID);
Drawable image = ImageOperations(getBaseContext(),"http://141.11.11.206/parca/" + Integer.toString(resimID) + ".jpg" ,"I" + Integer.toString(resimID) + ".jpg");
// I AM GETTING ERROR HERE ******************
resim.setImageDrawable(image); // *************************
}
}
new Handler().post(new ResimCek(Integer.parseInt(malzemeKodu))); instead of new Thread(r).start();
by any case if this is an Activity.. then
runOnUIThread(new ResimCek(Integer.parseInt(malzemeKodu))); `instead of new Thread(r).start();`
will also work..
You should create a handler :
final Handler myHandler = new Handler() {
#Override
public void handleMessage(Message msg)
{
/*do all your ui action here to display the image ()*/
resim.setImageDrawable(image);
}
};
And in your runnable when the image is downloaded call :
myHandler.sendEmptyMessage(0);
There are other options for handler you can find here
http://developer.android.com/reference/android/os/Handler.html

Loading picture show loading progress

I use the function to show picture:
Bitmap imageBitmap = loadBitmap(URL);
loadBitmap() as below:
private Bitmap loadBitmap(String url) {
try {
Bitmap bm = BitmapFactory.decodeStream((InputStream)this.fetch(url));
return bm;
}
catch(Exception e) {
e.printStackTrace();
return null;
}
}
And fetch() below:
public Object fetch(String address) {
try {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
catch(Exception e) {
e.printStackTrace();
}
return this;
}
I want to show the loading progress or a load.png while it loading.
And end with the picture loading finish and show it.
How can I do?
I try to make like ProgressDialog.
But I don't know how to use?
You can use AsyncTask to show a Progress Dialog on the PreExecute() method and hide/dismiss it in the PostExecute() method.
ProgressDialog prog = new ProgressDialog(this); // Create Progress Dialog
private class DownloadBitmap extends AsyncTask<Void, Integer, Void>{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
//Display progressDialog before download starts
prog.show();
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
prog.hide(); //Hide Progress Dialog else use dismiss() to dismiss the dialog
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
/*
* Perform download and Bitmap conversion here
*
*/
return null;
}
}
And finally call the AsyncTask through,
DownloadBitmap dd = new DownloadBitmap();
dd.execute();
You can use a ProgressBar for this.
Check out these links:
Tutorial 1
Tutorial 2
you can't do that directly, as Android doesn't support GIF files. So to away with that you have to create separate image (loading image into split images) and make animation of it. At the time of loading run the animation and once Bitmap avail stop animation and set Bitmap on ImageView
This example shows progressbar while downloading the image and later it is invisible.
public class ImageDownload extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
ImageView mainImageView = (ImageView) findViewById(R.id.imageView);
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
String imageurl = "http://ipadwallpaperportal.com/wp-content/main/2011_09/purple-flower-close-up-1024x1024-wallpaper.jpg";
ImageDownloadMessageHandler imageDownloadMessageHandler1 = new ImageDownloadMessageHandler(
progressBar, mainImageView);
ImageDownlaodThread imageDownlaodThread = new ImageDownlaodThread(
imageDownloadMessageHandler1, imageurl);
imageDownlaodThread.start();
}
class ImageDownlaodThread extends Thread {
ImageDownloadMessageHandler imageDownloadMessageHandler;
String imageUrl;
public ImageDownlaodThread(
ImageDownloadMessageHandler imageDownloadMessageHandler,
String imageUrl) {
this.imageDownloadMessageHandler = imageDownloadMessageHandler;
this.imageUrl = imageUrl;
}
#Override
public void run() {
Drawable drawable = LoadImageFromWebOperations(imageUrl);
Message message = imageDownloadMessageHandler.obtainMessage(1,
drawable);
imageDownloadMessageHandler.sendMessage(message);
System.out.println("Message sent");
}
}
class ImageDownloadMessageHandler extends Handler {
ProgressBar progressBar;
View imageTextView;
public ImageDownloadMessageHandler(ProgressBar progressBar,
View imageTextView) {
this.progressBar = progressBar;
this.imageTextView = imageTextView;
}
#Override
public void handleMessage(Message message) {
progressBar.setVisibility(View.GONE);
imageTextView.setBackgroundDrawable(((Drawable) message.obj));
imageTextView.setVisibility(View.VISIBLE);
}
}
Drawable LoadImageFromWebOperations(String strUrl) {
/**
* This is one method
*/
long x1 = System.currentTimeMillis();
Drawable d = null;
InputStream is = null;
try {
is = (InputStream) new URL(strUrl).getContent();
d = Drawable.createFromStream(is, "src name");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long x2 = System.currentTimeMillis();
long res = x2 - x1;
Log.v("Image Downloading Time", "" + res);
}

Categories

Resources