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.
Related
public class MainActivity extends Activity {
ImageView downloadedimg;
public class ImageDownloader extends AsyncTask<String,void,Bitmap> {
#Override
protected Bitmap doInBackground(String... urls) {
try{
URL url=new URL(urls[0]);
HttpURLConnection connection=(HttpURLConnection) url.openConnection();
connection.connect();
InputStream inputStream=connection.getInputStream();
Bitmap mybitmap= BitmapFactory.decodeStream(inputStream);
return mybitmap;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
}
public void downloadImage(View view) {
ImageDownloader task = new ImageDownloader;
Bitmap myImage;
try {
myImage = task.execute("https://www.google.co.in/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=0ahUKEwiOw5HvydXOAhVKqo8KHYHfAtIQjRwIBw&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FBart_Simpson&psig=AFQjCNFZSwEG2tjp15Km14uuzEsmZUZ_MQ&ust=1471974330385306");
downloadedimg.setImageBitmap(myImage);
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
downloadedimg=(ImageView)findViewById(R.id.imageView);
}
in the line
myImage = task.execute("some url to image address online");
the complier shows error that
incompatible type
required: android.graphics.Bitmap
found: android.os.AsyncTask "<"java.lang.String,void,android.graphics.Bitmap>
double code infront of java's bracket are not part of statement
#edit Thank you for previous advice i searched and found .get() method
i used task("").get() to return the bitmap image and code compiled without errors but now nothings happens when i click the download image button
AsyncTask.execute does not return the object downloaded. It can't, the entire idea of an AsyncTask is that its asynchronous. Any code that needs to use the result should either be put in onPostExecute (for UI changes) or at the end of doInBackground (for processing data).
Hello I am new with Google Glass and am wondering if I can display an image from the web as my background image.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String address = "http://archiveteam.org/images/1/15/Apple-logo.jpg";
Card myCard = new Card(this);
myCard.setText("Hello, World!");
myCard.setFootnote("First Glassware for Glass");
myCard.setImageLayout(Card.ImageLayout.FULL);
myCard.addImage(new URL(address));
View cardView = myCard.getView();
// Display the card we just created
setContentView(cardView);
}
I saw in a few threads that myCard.addImage(new URL(address)) was the solution, but I am getting the following error on that line.
The method addImage(Drawable) in the type Card is not applicable for the arguments (URL)
Any help would be appreciated, thanks in advance!
You shouldn't be gathering images on the UI thread. That is a network operation.
Create a separate Method running on a new thread to download the image, then save it as a bitmap. Then save that to the card;
DownloadImageTask(myCard).execute(address);
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
Card imgCard;
public DownloadImageTask(Card imgCard) {
this.imgCard= imgCard;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
imgCard.setImage(result);
}
}
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.
I have two functions that access the internet on the APP start. I've tried to use this post as a reference in order to have the popup dialog while my content loads.
The two functions I would use are:
getImage(); //Gets an image from the internet for an imageview
getJson(); //Where the app goes an parses a JSON object for a lazy load listview.
The problem I'm encountering with the post I referenced above is that I try to make the task return null but it causes the app to crash when I do this. So I have this:
private class DownloadTask extends AsyncTask<String, Void, Object> {
protected Object doInBackground(String... args) {
Log.i("MyApp", "Background thread starting");
try {
ImageView i = (ImageView) findViewById(R.id.currdoodlepic);
Bitmap bitmap = BitmapFactory
.decodeStream((InputStream) new URL(imageURL)
.getContent());
i.setImageBitmap(bitmap);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
getJson("all");
return "replace this with your data object";
}
I'm not sure what to return.
The type return of the method doInBackground depend of what you need at the post execution :
void postExecute(Object result); // AsyncTask method
Parameter "result" is the return value of doInBackground. So if you need nothing you return NULL.
I found the exact answer here. Here is the code:
ImageView mChart = (ImageView) findViewById(R.id.imageview);
String URL = "http://www...anything ...";
mChart.setTag(URL);
new DownloadImageTask.execute(mChart);
The Task class:
public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
ImageView imageView = null;
#Override
protected Bitmap doInBackground(ImageView... imageViews) {
this.imageView = imageViews[0];
return download_Image((String)imageView.getTag());
}
#Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
private Bitmap download_Image(String url) {
...
}
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.