In this tutorial, I plan to download 1 image and 1 text from the internet on the click of respective buttons on the android phone.
NOTE: I have also incidentally used Absolute Layout so that the buttons, the text and the image are all seen on the same screen even after being fetched.
Since fetching data from the internet can be a time-consuming task and a very unpredictable one at that, so, it would best be done in a separate thread rather than the UI/main thread. The basics of this have been discussed in the previous tutorial on Handlers and Threads.
To go to the application code directly, on the click of a button “Get Image”, I want to get an image whose URL is hard-coded in the program. For that first, I must open an HTTP connection to the server and then request for the image.
Hence is the code for opening and making an HTTP Connection:
private InputStream openHttpConnection(String urlStr) {I will not be explaining this code much as most of this is based on the java.net package. This code would be exactly same even if we were to write this in regular java code, not meant for android usage. In brief, I have opened a URLConnection, checked if it is an instance of HttpURLConnection, set the parameters required and made the ‘connection’ finally by calling the connect() method. Then, I check if the response code is OK and I get a handle to the input stream.
InputStream in = null;
int resCode = -1;
try {return in;
URL url = new URL(urlStr);} catch (MalformedURLException e) {
URLConnection urlConn = url.openConnection();
if (!(urlConn instanceof HttpURLConnection)) {
}throw new IOException ("URL is not an Http URL");
HttpURLConnection httpConn = (HttpURLConnection)urlConn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
resCode = httpConn.getResponseCode();
if (resCode == HttpURLConnection.HTTP_OK) {
}in = httpConn.getInputStream();
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
So, this is a utility method that I will use for fetching image as well as text.
Now, coming to fetching the image. I want to fetch it when the end user clicks on a button “Get Image”. So the code associated with the button click is here:
getImageButton = (Button)findViewById(R.id.Button01);
getImageButton.setOnClickListener( new OnClickListener() {}
Override
public void onClick(View v) {
downloadImage(http://www.android.com/media/wallpaper/gif/android_logo.gif);
});
So the fetching of the image is in the downloadImage() method, which is given the URL of the android logo. Here is the method:
private void downloadImage(String urlStr) {This method looks a bit complicated. First, let us look at the basics. If I were not fetching this in a separate thread, I would have just the 3 lines of code that is in Bold and highlighted. Open a connection, fetch the bitmap and close the connection. However, since this is a typical task that is unpredictable in its response time, it is best done in a separate thread of its own. So, before I start a new thread, I let the UI thread to show a ProgressDialog as shown in
progressDialog = ProgressDialog.show(this, "", "Fetching Image...");
final String url = urlStr;
new Thread() {
public void run() {
InputStream in = null;
Message msg = Message.obtain();
msg.what = 1;
try {
in = openHttpConnection(url);messageHandler.sendMessage(msg);
bitmap = BitmapFactory.decodeStream(in);
Bundle b = new Bundle();
b.putParcelable("bitmap", bitmap);
msg.setData(b);
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}.start();
progressDialog = ProgressDialog.show(this, "", "Fetching Image...");
Then, I start a new thread. I make the URL string accessible within the new thread by making it a final variable. Since message is an object that I can use for communication between threads, I create a Message object in the thread. Then, I set the message number to 1, so that I can use it later.
Then, I bundle my bitmap already fetched into a Bundle object that can be sent back in the Message object.Message msg = Message.obtain();
msg.what = 1;
Bundle b = new Bundle();
b.putParcelable("bitmap", bitmap);
msg.setData(b);
Once I close the input stream as in:
in.close();the thread has completed the job. So, I notify the main / UI thread through this method and also pass on the Message object:
messageHandler.sendMessage(msg);This completes the fetching of the image in a separate thread. Now, how do I retrieve the image from the Message object in the main thread?
As soon as the child thread notifies, the method called back in the main thread is the handleMessage(msg) method. It is in this method that I retrieve the bitmap and set it to the ImageView in the UI. Here it goes:
private Handler messageHandler = new Handler() {};
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
ImageView img = (ImageView) findViewById(R.id.imageview01);case 2:
img.setImageBitmap((Bitmap)(msg.getData().getParcelable("bitmap")));
break;
……….
}
progressDialog.dismiss();
}
Within this method, first I check the msg.what variable to see what the type of message I am expecting is. If it is 1, which I had set in downloadImage(..) method, then, I do the required things to get a handle to the ImageView object and then give the bitmap to it.
How do I fetch the data from the msg object? Through getData(). Then I use the key “bitmap” to retrieve the bitmap and cast it to Bitmap before setting it to the ImageView. Finally, I dismiss the progress dialog.
I hope this is clear. This example not only shows HTTP Connection from Android but also the Thread-to-thread communication through handler, message exchange.
In a very similar fashion, I also fetch the text. On click of the Get Text button, here is the code that gets invoked:
getTextButton.setOnClickListener(new OnClickListener() {});
@Override
public void onClick(View v) {
downloadText(http://saigeethamn.blogspot.com/feeds/posts/default);
}
The downloadText() code is here:
private void downloadText(String urlStr) {
progressDialog = ProgressDialog.show(this, "", "Fetching Text...");
final String url = urlStr;
new Thread () {
public void run() {}
int BUFFER_SIZE = 2000;
InputStream in = null;
Message msg = Message.obtain();
msg.what=2;
try {
in = openHttpConnection(url);} catch (IOException e) {
InputStreamReader isr = new InputStreamReader(in);
int charRead;
text = "";
char[] inputBuffer = new char[BUFFER_SIZE];
while ((charRead = isr.read(inputBuffer))>0)
{
//---convert the chars to a String---
String readString =
String.copyValueOf(inputBuffer, 0, charRead);
text += readString;
inputBuffer = new char[BUFFER_SIZE];
}
Bundle b = new Bundle();
b.putString("text", text);
msg.setData(b);
in.close();
e.printStackTrace();
}
messageHandler.sendMessage(msg);
}
}.start();
And the way the text is handled in the main thread handleMessage(..) method is here:
case 2:The complete code can be downloaded here
TextView text = (TextView) findViewById(R.id.textview01);
text.setText(msg.getData().getString("text"));
break;
Thanks for your understanding.
NOTE: the blog editor is posing major problems in editing - it is jumbling up the whole post esp. when I use the " feature. So, please bear with me if somethings look garbled. I have tried my best to work around the editor problem. This has been noticed only in the last 3 posts of mine. Hope it gets fixed soon.
Hi Sai Geetha...
ReplyDeleteReally its very much useful samples.
But i am facing an issue. when i am trying to download some images using this code its throwing some error as shown below ..
06-21 16:07:18.493: DEBUG/skia(603): --- decoder->decode returned false.
Can u please look in to that once and help us to get rid of that error.
I didn't found any fruitful solution even in the forums also
Thanks and Regards,
Pavan UVR
The above code is working for most of the images
ReplyDeleteBut its not working for the image
http://jquery.com/demo/thickbox/images/plant4.jpg
i donno why its not working....
can u please check this once
Hi Pavan....
ReplyDeleteYou can always run your program into debug mode and check if any exception occurred. Regarding your query, if the resource file (that is, the image that u r trying to load) is too big, then it might not load... This might be a reason too.. have u checked the code for any other images?
Yes Arin, The same code is working well for the other Images.
ReplyDeleteHi Pavan,
ReplyDeleteDo you realize that the image in my code is 12 KB while the one you are trying is 207 KB. Resources are very limited in the mobile domain. Please remember that.
Hey geetha,
ReplyDeletenice article. I am currently using async task to do my network operation but what i am planning to do is use a background thread to do my data download from the webservice meanwhile i will display the old data from the database.
my question is if i use a thread and handler in my main activity and the user moves to another activity when the thread finishes its download how will the handler work? will it automatically go to the activity that created the handler??
Hi Sandeep,
ReplyDeleteI think you need to see this google video so that you validate your design for backend web service calls against thier best practices:
http://www.youtube.com/watch?v=xHXn3Kg2IQE
and doc at
http://dl.google.com/googleio/2010/android-developing-RESTful-android-apps.pdf
Dear Sister Geetha, my name is Bala, i am a B-Tech student, the scope of my final year project is to "Take an image from android mobile camera and upload to the web server. once start the application, the device should automatically capture image from the camera for every few seconds and upload to web server in real time".
ReplyDeletei am very new to Android as well as java and struggling with the Android code on mobile side and php code on server side. i am using eclipse SDK version 3.6.1
please help me give some advice or if possible give me the source code to perform the above mentioned task. i am working on this for 3 months day & night, so far no solution yet. Today only i come across your blog and very excited with all your explanation about android.
kindly contact to my Email: "mtbalaict@gmail.com" i will send you the code that i have.
my mobile: +65 91310837
i am from tamilnadu, currently working and studying in singapore.
Thanks a lot for your help... jai shiridi Sairam!
Hi Geeta,
ReplyDeleteI have gone through some of your examples and found them to be really helpful.
I have been trying out a Android Client app running in emulator which must be able to communicate to a Server running on my PC through text messages. For the whole purpose I have been using the HTTP protocol and its methods,but haven't been successful so far.
Can you please provide me some help in this regard, a example for such a Client Server is what I am looking for.
hai geetha u r code really useful so i have one doubt i want to connect to some site and search for meaning and retrive the first meaning of given results in html form can u heip me to finish that work
ReplyDeletehi geetha,
ReplyDeletei downloaded ur app and tried to downlaod n view an image on another device(recognised by a static IP) connected to the same wifi as the first device....its wasnt possible....it worked for almost all low-size images as mentioned above but cudnt recieve the image from the other device's sdcard...can u please shed some light on this topic???
Will it possible for you to provide a tutorial on how to parse XML response and display it?
ReplyDeleteThanks
hi geetha,
ReplyDeletei have worked out this httpconnection samples reading images and text. its really useful to my project. thanks a lot
Hi Geetha,
ReplyDeleteA vry helpful artical u shared with all of us..
I m new to android..
i need to establish a https connection and send/recieve data...
can u plz guide me.how to approach towards my job
Thanks and Regards
Nisha
Thank you,Its really Helpful.
ReplyDeletehi sai geetha,
ReplyDeleteThanks for such a informative tutorial..i've been facing an issue with the emulator..How to enable internet on my AVD? i am using windows7 and a data card for internet access...
i want to test some apps(webview,maps etc)...there were so many posts on net about this but none solved my problem..any kinda inputs would be helpful..thank you..BTW ur tutorials are very helpful...
Hi, Thanks for this tutorial, but my app is very slow to parsing data from server with JSON... I've tryed to change the buffer size in: BufferedReader reader = new BufferedReader(new InputStreamReader(is), 8*1024); But is the same....Sometimes i have to wait 15 seconds and then the activity is shown. (Tested with Galaxy Tab with 1Ghz CPU, 512Mb RAM and 2MB/s Wifi connection).
ReplyDeleteHello Sai Mam,
ReplyDeleteYour blog's help me lot...
Thank you...
Hi Sai Geetha!! Your posts are really helpful.
ReplyDeleteHi Guys is there any interested person to work with me on a android project?
My email id is karim.ece042@gmail.com
Hi, i am working on Android Development and looking forward to work more on interesting projects in android.You can contact me @ sav.accharya@gmail.com.
DeleteThis comment has been removed by the author.
ReplyDeleteDear Sai,
ReplyDeleteFirst of all many thanks for your clear blog. I am pretty new in Android. I tried some of your samplecodes and after solving some Eclips-"problems" it works very good..
In this sample I tried, without success, to change the code so it can load and show two images (different url) after pressing the button. I am messing with Bitmap1 and Bitmap2. Is there someone who can help me with the right structure? Thanks Eugene.
your tutorials are the best.......
ReplyDeleteHello Sai, i have a problem at downloading image.
ReplyDeleteIt seems its problem around the bitmap,cause i m geting NullPointerException on
img.setImageBitmap((Bitmap) (msg.getData().getParcelable("bitmap")));
i have everythin from your guide so really no clue why i have this problem.
Can u help me with solving this ? :)
please tell me how to pass a string to another emulator.. using tcp socket connection
ReplyDeleteHello All,
ReplyDeleteI'm an M.Tech student working on an android project.
I need to send some data from the html page to android phone.
As I'm new to this, I need some help.
Expecting an urgent reply.
Thanks.....
hello sir,
ReplyDeletei mae an app using http connection in that i sent data from android app to mysql database sucessfully but am unable to fetch data from mysql database wht to do plz tell me,
and cant we do that without using json? just want to print data fetch in android app from mysql??
Please post your code.
Delete