Image downloading via multithreading not working in Android - android

I have to download an image from a url and then show the downloaded image in a imageview on the UI.
For this i am using the code mentioned below:
public class ShowUIData extends AsyncTask<Void, Void, Void> {
String productvalues[];
Drawable productimagebitmap;
#Override
protected Void doInBackground(Void... params) {
productvalues = hb.getProductDetailsWithJson(id + 1);
if (productvalues != null) {
productimagebitmap = getImage(productvalues[3]);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (productvalues != null) {
// Set the values obtained from the database.
// Check if image returned from URL is not null.
if (productimagebitmap != null) {
ImageView productimage = (ImageView) findViewById(R.id.productimage);
productimage.setImageDrawable(productimagebitmap);
}
}
dismissDialog();
}
// Download image from URL obtained for database.
private Drawable getImage(String address) {
try {
Log.i("product details", "starting image download");
URL url = new URL(address);
URLConnection conn = url.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
Drawable d = Drawable.createFromStream(is, "src name");
is.close();
return d;
} catch (Exception e) {
Log.i("the url", address);
e.printStackTrace();
return getApplicationContext().getResources().getDrawable(
R.drawable.noimage);
}
}
A valid URL is being passed to the getImage function and no exception is being thrown , still the image is not being set on the imageview. When i debug my application, then the image is setting properly.
I believe i need to put a blocking call until the image is download and then call image.setImageDrawable.
What is the problem occuring over here. I am not able to figure out why i am not able to load any images and why only when i debug , i see an image?
thank you in advance.

you should try this example. It runtime fetches images from the url and also displays it in listview. I think this will help you.

Non UI thread can't update UI component. Use handler to update UI component.

Related

How to display dynamic ImageView from URL in infoWindow

I'm trying to download an image and show it as an ImageView in my infoWindow , working with InfoWindowsAdapter , i put all the necessary code in the getInfoContents() method, but i can't get the image , in fact i can get it but still can't show it .
As i read in the documentation,i have to recall the treatment to set the downloaded image , i have to use showInfoWindow() method because it's the only way to do it . I tried to use it in getInfoContents() just before the return but , it blocks my app , need help !
This is my getInfoContents() :
public View getInfoContents(Marker marker) {
// set the view
View v = (View) getLayoutInflater().inflate(R.layout.info_window,null);
//assign values to the view field
ImageView imagePlace =(ImageView) v.findViewById(R.id.imageview1);
TextView tvLocality = (TextView) v.findViewById(R.id.tv_place);
//setting values with the parameter
Picasso.with(getApplicationContext()).load(url_image_place).into(imagePlace);
tvLocality.setText(marker.getTitle());
//marker.showInfoWindow();
return v;
}
This my downloadIcon() :
private Bitmap downloadIcon(String iconURL) {
Bitmap bmImg = null;
try {
URL url = new URL(iconURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
} catch (IOException e) {
e.printStackTrace();
bmImg = null;
}
return bmImg;
}
EDIT :
I used picasso to download my image , but the image is shown only after the second click , and any marker's infowindow that use the same image get the image in the first time , it means that the image have to be downloaded first !! i edited my getInfoContents() and i'm not using downloadIcon() anymore !
Using Picasso, this is extremely easy. Simply write:
String url = ...;//Your url
ImageView imageView; //Your ImageView
Picasso.with(context).load(url).into(imageView);
Or, If you want to do it yourself, you can implement an AsyncTask:
Definition:
private class ImageDownloader extends AsyncTask {
#Override
protected Bitmap doInBackground(String... param) {
return downloadIcon(param[0]);
}
#Override
protected void onPostExecute(Bitmap result) {
//Handle your result, i.e. your bitmap
}
}
Execution:
new ImageDownloader().execute(iconURL);
You should not dowmload image by using main UI thread, so you need another thread to do it, something like:
public void setImage(final ImageView img, final String iconURL)
{
Thread thread = new Thread(new Runnable() {
#Override
public void run()
{
Bitmap bmImg;
try {
URL url = new URL(iconURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
}
catch (IOException e) {
e.printStackTrace();
bmImg = null;
}
//after downloading, then talk to main ui
runOnUiThread(new Runnable()
{
#Override
public void run()
{
img.setImageBitmap(bmImg);
}
}
}}).start();
}
Hope this help!

How can I pass combined URL as a parameter in android?

I'm working on the music streaming service project. I like to show thumbnail jacket images when I started the application in the first place.
I've fetched all the String Json results, and I've converted Jason results to hashmap by using Gson lib.
What I'm trying to do is combine the base url with map value and return? or pass the result, so that I can use the result with another thread in order to show the thumbnail images. please give me some answers..:(
MainActivity.java
private static final String baseURLforgetNewMusic = "https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/";
....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
new Connection().execute(getMusicInfo_URL + "getNewMusic.php");
// Connect to the server.
}
private class Connection extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
return getMusicInfo(urls[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
....
private String getMusicInfo(String url) {
InputStream inputStream = null;
String inputStr = "";
HashMap<String, Object> map = new HashMap<String, Object>();
try {
URL getMusicUrl = new URL(url);
conn = (HttpURLConnection) getMusicUrl.openConnection();
conn.setDoInput(true);
conn.connect();
Log.d(TAGCP, "MADE POST REQUEST TO THE GIVEN URL");
inputStream = conn.getInputStream();
if (inputStream != null) {
inputStr = Util.convertInputStreamToString(inputStream);
Log.i(TAGCS, inputStr);
Music list = new Gson().fromJson(inputStr, Music.class);
for (Music.MusicInfo info : list.musicInfo) {
System.out.println(baseURLforgetNewMusic + info.artists
+ "/" + info.file_name);
}
} else {
inputStr = "Did not work!";
Log.d(TAGRR, inputStr);
}
} catch (Exception e) {
Log.i("InputStream", e.getLocalizedMessage());
}
return inputStr;
}
Results: (I want to use these url to show thumbnail images on the main view.)
I/System.out(22054): https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/BrunoMars/Grenade
I/System.out(22054): https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/BrunoMars/Justthewayyouare
I/System.out(22054): https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/Beenzino/Aquaman
I/System.out(22054): https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/Gummy/Thinkaboutme
Try using volley to load your images. It will be faster and easier to use than Universal Image Loader. The library contains a class called NetworkImageView that will load all of your images for you.
Try showing images with this library:
https://github.com/nostra13/Android-Universal-Image-Loader
You can pass the list of URLs here and will show images in a gridview.
If you want to make something cool like CoverFlow for showing album covers use this:
https://github.com/Polidea/android-coverflow

Android AsyncTask will not work downloading image

I am hoping someone can help me with a problem I have been having. I am in the process of making my app work on versions greater than 3.0 so I can only perform GUI tasks on the UI Thread. I have got the following code, I am getting no compile errors but it is not working. In the log I get the following error:
I/AndroidRuntime(464): NOTE: attach of thread 'Binder Thread #3' failed
Thank you for your help!
new DownloadImageTask().execute(imgURL); //imgURL is declared as string URL
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
protected void onPostExecute(Bitmap result) {
((ImageView) findViewById(R.id.imgCity)).setImageBitmap(bmp);
}
protected Bitmap doInBackground(String... params) {
return loadImage(params[0]);
}
}
public Bitmap loadImage(String poiURLimg) {
try {
URL ulrn = new URL(poiURLimg);
HttpURLConnection con = (HttpURLConnection) ulrn.openConnection();
InputStream is = con.getInputStream();
bmp = BitmapFactory.decodeStream(is);
if (null != bmp)
return bmp;
} catch (Exception e) {
}
return bmp;
}
The Binder Thread #3 error is not related to the code in your app. There are a number of potential causes usually related to something in eclipse. You can read this post which gives some examples.
As to why the Bitmap wont load - in your onPostExecute you are setting the Bitmap for that ImageView to bmp. Bmp is name of the value that your loadImage method creating the bitmap returns. It is not the name of the Bitmap you pass as an argument into onPosExecute - that is Bitmap result. Change bmp to result and it should work.
A couple things to try. First, make sure you've added the INTERNET permission to your AndroidManifest.xml file. You'll need that to download images from the internet and your app will crash without it (although it doesn't sound like this is your issue)
Try using this for your loadImage() method:
public static Bitmap loadImage(String src)
{
try
{
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
}
Here is an example of a DownloadImageTask that I wrote and use in my apps currently (so I know it works correctly):
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
#Override
protected Bitmap doInBackground(String... params)
{
return loadImage(params[0]);
}
#Override
protected void onPostExecute(Bitmap result)
{
if (isCancelled() || result == null)
return;
((ImageView) findViewById(R.id.image_view)).setImageBitmap(result);
}
}

Fetching images from a URL into an ImageView

I am continuing my efforts in making an app for my school newspaper. My newest challenge is to get every club and organization logo to appear in a ImageView that is in an Activity with other details about the club.
For obvious reasons I don't want to store all of these images within the app, I would rather fetch them from a URL. I think a way to do this would be the following snippet:
Intent intent = getIntent();
Bitmap bm = null;
try {
bm = BitmapFactory.decodeStream((InputStream)new URL(intent.getStringExtra("keyLogo")).getContent());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
detailsLogo.setImageBitmap(bm);
I am getting a URL from an XML file that I created which has all of the clubs on campus and their information. This way I only have to change the XML when I want to change something within the app.
The problem here is that it throws a NetworkOnMainThread exception. Could this be put into an AsyncTask within my activity and run that way? Any advice would be appreciated.
EDIT: The linked question does not answer my needs. One of the answers to it is close, but my questions specifically needs an Async task which that questions accepted answer does not include.
Here is the finished activity using the accepted answer and other pieces:
public class OrgDetails extends Activity {
/*******************************************************************
* Async Task
******************************************************************/
private class GetImageFromServer extends AsyncTask<String, Void, Bitmap> {
String url;
Context context;
private Bitmap image;
ImageView detailsLogo = (ImageView)findViewById(R.id.detailsLogo);
public GetImageFromServer(String url, Context context){
this.url = url;
this.context = context;
}
#Override
protected Bitmap doInBackground(String... params){
try{
URL urli = new URL(this.url);
URLConnection ucon = urli.openConnection();
image = BitmapFactory.decodeStream(ucon.getInputStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return image; //<<< return Bitmap
}
#Override
protected void onPostExecute(Bitmap result){
detailsLogo.setImageBitmap(result);
}
}
/*******************************************************************
* End Async Task
******************************************************************/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.orgdetails);
TextView detailsSname = (TextView)findViewById(R.id.detailsSname);
TextView detailsLname = (TextView)findViewById(R.id.detailsLname);
TextView detailsDescription = (TextView)findViewById(R.id.detailsDescription);
Intent intent = getIntent();
detailsLname.setText(intent.getStringExtra("keyLname"));
detailsSname.setText(intent.getStringExtra("keySname"));
detailsDescription.setText(intent.getStringExtra("keyDescription"));
String str_url = intent.getStringExtra("keyLogo");
GetImageFromServer asyObj = new GetImageFromServer(str_url,OrgDetails.this);
asyObj.execute("");
}
}
Change your code using AsyncTask for getting image from sever instead of doing Network Operation on Main UI thread. Create an inner class of Activity by extending AsyncTask as:
private class GetImageFromServer extends AsyncTask<String, Void, Bitmap> {
String url;
Context context;
public GetImageFromServer(URL url,Context context){
this.url=url;
this.context=context;
}
#Override
protected Bitmap doInBackground(String... params) {
bm = BitmapFactory.decodeStream((InputStream)new URL(url).getContent());
return bm; //<<< return Bitmap
}
#Override
protected void onPostExecute(Bitmap result) {
detailsLogo.setImageBitmap(result);
}
}
and execute AsyncTask as from Activity:
String str_url=intent.getStringExtra("keyLogo");
GetImageFromServer asyObj=new GetImageFromServer(str_url,Your_Activity.this);
asyObj.execute("");
You get a NetworkOnMainThread exception as you are attempting to perform network operations in the UI thread.
You should put this into an AsyncTask as you suggested, and your download code should retrieve the InputStream rather than cast the content like so:
URL url = new URL(path);
URLConnection ucon = url.openConnection();
Bitmap image = BitmapFactory.decodeStream(ucon.getInputStream());
If you also want more flexible control over your images, consider using Image adapters for your Bitmap objects. These are containers that extend the BaseAdapter and can provide you extra controls to manipulate your images e.g. scaling.
Yes you definitely want to do your grabbing of images over the network on a separate thread. You could set up your doInBackground to get the image and then in the onpostexecute set the bitmap to the imageview.

I my using google mapV2 and i m downloading image from google place api and want to display in the popup

i m using all the classes for geting image through Url.
ImageView imV= ((ImageView) view.findViewById(R.id.badge));
// Image url
String image_url = "http://maps.gstatic.com/mapfiles/place_api/icons/cafe-71.png";
final int stub_id = R.drawable.ic_action_search;
// ImageLoader class instance
ImageLoader imgLoader = new ImageLoader(getApplicationContext());
// whenever you want to load an image from url
// call DisplayImage function
// url - image url to load
// loader - loader image, will be displayed before getting image
// image - ImageView
imgLoader.DisplayImage(image_url,stub_id ,imV);
but it is displaying the default image,rather than Url downloaded image.
https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/GoogleMap.InfoWindowAdapter
i m using infowindowAdapter class of goolge and its says that i cn't change the image when once data & image is loaded in the window,thts why its displaying first default image..... and not changing later
so is there any other way?
thanks in advance
I'm having the same problem.
I've solved it with a asyncTask.
Something like this
private Drawable _infoImageDrawable;
public class MyMapActivity extends MenuActivity
{
.....code code code....
protected void handleMarkerClicked(final Marker marker, final String url) {
new AsyncTask<Void, Void, Void>()
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
_infoImageDrawable = null;
}
#Override
protected Void doInBackground(Void... params)
{
InputStream is;
try {
is = (InputStream) new URL(url).getContent();
_infoImageDrawable = Drawable.createFromStream(is, "");
} 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);
marker.showInfoWindow();
}
}.execute();
}
}
Then I just set the drawable in the InfoWindowAdapter to null first(remove old image) and to _imageInfoDrawable second.
It works - but i would like a better solution.

Categories

Resources