task.execute url to bitmap mismatch - android

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).

Related

Convert URL to Bitmap results in a network error in Android

I'm trying to load an image from an URL to a Bitmap but I am getting a NetworkOnMainThreadException error but I don't know why.
This is the method I am using:
public Bitmap getBitmapFromURL(String src) {
try {
java.net.URL url = new java.net.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;
}
}
I also tried to load the image to a Target using Picasso library, because in the end, I want to get the dominant color from this image using Palette. This is the code I have using Picasso:
Picasso.with(MovieDetails.this)
.load("https://image.tmdb.org/t/p/w500" + backdrop)
.into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Palette palette = Palette.from(bitmap).generate();
System.out.println(palette.getVibrantSwatch().toString().substring(16, Math.min(palette.getVibrantSwatch().toString().length(), 22)));
LinearLayout lLayout = (LinearLayout) findViewById(R.id.layout_bg);
lLayout.setBackgroundColor(Color.parseColor("#"+ palette.getVibrantSwatch().toString().substring(16, Math.min(palette.getVibrantSwatch().toString().length(), 22))));
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
I put this inside my onCreate method, but I am getting "method does not override method from its superclass" errors in all the three #Override methods.
I managed to solve my problem by using an AsyncTask as it follows:
I put this in the end of my Activity:
public class MyAsync extends AsyncTask<Void, Void, Bitmap>{
#Override
protected Bitmap doInBackground(Void... params) {
try {
URL url = new URL("https://image.tmdb.org/t/p/w500" + backdrop);
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;
}
}
}
Please note that inside this method I put the URL for the image.
To access the Bitmap inside my Activity and get the dominant color using Palette I did this:
MyAsync obj = new MyAsync(){
#Override
protected void onPostExecute(Bitmap bmp) {
super.onPostExecute(bmp);
Bitmap bm = bmp;
if (bm != null && !bm.isRecycled()) {
Palette palette = Palette.from(bm).generate();
System.out.println(palette.getVibrantSwatch().toString().substring(16, Math.min(palette.getVibrantSwatch().toString().length(), 22)));
LinearLayout lLayout = (LinearLayout) findViewById(R.id.layout_bg);
lLayout.setBackgroundColor(Color.parseColor("#"+ palette.getVibrantSwatch().toString().substring(16, Math.min(palette.getVibrantSwatch().toString().length(), 22))));
}
}
};
obj.execute();
This code is inside my onCreate method.
The way to correct the first issue is to perform that action in a Thread or Runnable, There is a flag you can set something like StrictModeEnabled or something like that, but that's bad, don't resort to that.
As far as picasso, i dont know about the overriding methods from superclass thing, i'd try to do it in onViewCreated instead of onCreate

Setting image from url

I have an image view in my Android app, where I have to set a simple image from url. I tried the below code, but it doesn't set the image from url.
try {
URL url = new URL("https://drive.google.com/...");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream stream = connection.getInputStream();
Bitmap teamBmpImage = BitmapFactory.decodeStream(stream);
teamImgView.setImageBitmap(teamBmpImage);
}
catch (Exception e) {
}
Could someone guide me to achieve this please?
UPDATED CODE: Which gives Nullpointer exception
public class AboutActivity extends ActionBarActivity {
ImageView teamImgView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
teamImgView = (ImageView) this.findViewById(R.id.teamImageView);
new DownloadImageTask(teamImgView).execute("http://docs.oracle.com/javase/tutorial/2d/images/examples/strawberry.jpg");
}
class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
//pd.show();
}
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;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
//pd.dismiss();
bmImage.setImageBitmap(result);
}
}
}
I guess you are executing your code on the MainThread, which leads to a NetworkOnMainThreadException in android. Try to execute your code asynchronous like in the example below
new AsyncTask<String, Integer, Bitmap>() {
#Override
protected Bitmap doInBackground(String... params) {
try {
URL url = new URL(params[0]);
return BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap bm) {
ImageView teamImgView = (ImageView) findViewById(R.id.teamImageView);
teamImgView.setImageBitmap(bm);
}
}.execute("https://drive.google.com/uc?....");
You can use Picasso library and here is a detailed tutorial on how to do this.
This is very simple example usage
Picasso.with(activityContext)
.load("https://drive.google.com/uc?....")
.placeholder(R.drawable.image_name)
.into(imageView);
As bojan says you can use Picasso library wich handles many common pitfalls of image loading on Android.
Picasso.with(context).load("http://myurl/myImage.png").into(imageView);
Picasso
Anyway, check out this threat too :)
How to load an ImageView by URL in Android?
Try following this link:
http://www.tutorialsbuzz.com/2014/11/android-volley-url-imageview.html
This will help you to load your image using Volley library which will do all the networking stuff on networking thread and set your image on main UI thread. It has also the LRUCache part which you can skip if you want.

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.

What to return for an Async Task

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) {
...
}

Categories

Resources