I need to load an image from the web in my app, I found a good example here, but I can't figure out how to use the returned Bitmap in my Main Activity :
the class :
public class GetImageFromServer extends AsyncTask<Void, Void, Bitmap {
private String sURL;
GetImageFromServer(String urlParam) {
sURL = urlParam;
}
#Override
protected Bitmap doInBackground(Void... urlParam) {
Bitmap bmp = null;
//ImageView img = (ImageView) findViewById(R.id.imageView1);
try {
URL url = new URL(sURL);
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (Exception ex) {
Log.println(1, "Profile:getImg", ex.getMessage());
}
return bmp;
}
#Override
protected void onPreExecute() {}
}
And the MainActivity code :
String urlImage = "http://www.xxxxxx.com/css/images/xxxxxx.png";
GetImageFromServer gifs = new GetImageFromServer(urlImage);
gifs.execute();
if(person.has("Avatar")) {Avatar.setImageBitmap( gifs.execute())}
The error is :
gifs.execute()
Thanks for your help !
Add :
I added this "cancel(true)" because I have connection problems to JSON webservices after severals start/debug/close, but I doesn't seem to work :
#Override
protected Bitmap doInBackground(String... urlParam) {
if (isCancelled())
this.cancel(true);
Bitmap b = null;........
and
#Override
protected void onPostExecute(Bitmap result) {
// use the result
mImageView.setImageBitmap(result);
this.cancel(true);
}
Could the assynctasks prevent my app to connect to my webservices ?
There is a good library for doing async image loadings, here is a link: https://github.com/square/picasso.
Or you could follow this approach:
public class LoadImageAsyncTask extends AsyncTask<String, Void, Bitmap> {
private ImageView mImageView;
public LoadImageAsyncTask(ImageView imageView) {
mImageView = imageView;
}
#Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
try {
URL url = new URL(params[0]);
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (Exception ex) {
Log.println(1, "Profile:getImg", ex.getMessage());
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}
In your activity call:
LoadImageAsyncTask task = new LoadImageAsyncTask(findViewById(R.id.yourImageId)).execute(stringUrl);
you have to implement a callback
your asynctask
public class GetImageFromServer extends AsyncTask<Void, Void, Bitmap> {
private String sURL;
private Bitmap b;
YourCallback mOwner;
GetImageFromServer(YourCallback owner, String urlParam) {
sURL = urlParam;
mOwner = owner;
}
#Override
protected Bitmap doInBackground(Void... urlParam) {
try {
URL url = new URL(sURL);
b = BitmapFactory.decodeStream(url.openConnection()
.getInputStream());
} catch (Exception ex) {
Log.println(1, "Profile:getImg", ex.getMessage());
}
return b;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(Bitmap result) {
// use the result
super.onPostExecute(result);
if (mOwner != null)
mOwner.CallbackFunction(result);
}
public interface YourCallback {
void CallbackFunction(Bitmap result);
}
}
your MainActivity
public class MainActivity extends Activity implements YourCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
GetImageFromServer gifs = new GetImageFromServer(urlImage, b);
gifs.execute();
}
#Override
public void CallbackFunction(Bitmap result) {
if (person.has("Avatar")) {
Avatar.setImageBitmap(result);
}
}
}
Related
I have implemented a simple custom progress dialog, which I show on onPreExecute method. However after the show of dialog AsycnTask does not progress to doInBackground method. Hence dialog is shown for ever. When I comment out the dialog show it works fine. Please see the code below. How can I resolve this.
public class CustomProgressDialog extends ProgressDialog
{
public CustomProgressDialog(Context context) {
super(context);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.customprogress);
}
#Override
public void show() {
super.show();
}
}
private CustomProgressDialog getProgressDialog() {
CustomProgressDialog p = new CustomProgressDialog(activity);
p.setCancelable(true);
p.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
loadMainFragment();
if(imageTask != null)
imageTask.cancel(true);
}
});
private class ImageDownloader extends AsyncTask<String, Void, Bitmap> {
CustomProgressDialog ringProgressDialog = null;
Bitmap bitmap = null;
#Override
protected Bitmap doInBackground(String... param) {
Bitmap b = downloadBitmap(param[0]);
image = b;
return b;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
ringProgressDialog = getProgressDialog()
ringProgressDialog.show();
// after showing this no progression
}
#Override
protected void onPostExecute(Bitmap result) {
if(isCancelled())
return;
if (result == null)
return;
super.onPostExecute(result);
bitmap = result;
// do work
if(ringProgressDialog != null)
ringProgressDialog.dismiss();
}
private Bitmap downloadBitmap(String url) {
Bitmap bm = null;
InputStream is = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.setConnectTimeout(Utils.timeout);
conn.setReadTimeout(Utils.timeout);
conn.connect();
is = conn.getInputStream();
bm = Utils.decodeBitmapFromInputStream(is,width, width, true);}
catch(Exception e){}
return bm;
}
I'm trying to display an image from a URL in an InfoWindowAdapter, but it does not show me the image. I'm using Volley to load images.
Does anyone have an idea how to solve this problem?
Thanks for your help!
I got it solve the problem. It was necessary to download the image manually. How did the code:
private void loadImage(Marker marker) {
if (((BitmapDrawable) localImage
.getDrawable()) == null) {
new DownloadImage(localImage, marker).execute(urlImage);
}
private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
private ImageView icone;
private Marker marker;
public DownloadImage(ImageView imageView, Marker marker) {
icone = imageView;
this.marker = marker;
}
#Override
protected Bitmap doInBackground(String... URL) {
String imageURL = URL[0];
Bitmap bitmap = null;
try {
// Download Image from URL
InputStream input = new java.net.URL(imageURL).openStream();
bitmap = BitmapFactory.decodeStream(input);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
if (result != null) {
icone.setImageBitmap(result);
} else {
icone.setBackgroundResource(R.drawable.ic_launcher);
}
marker.showInfoWindow();
}
}
I have the queryAppIcon() method that queries and stores images in the array appIconDrawable. However, I'm only getting blank where images should pop up. Please let me know if I should post any other relevant code
This is the relevant code inside the ViewActivity:
// global vars
final Drawable[] appIconDrawable = null;
int i;
public Drawable[] queryAppIcon() throws ParseException, IOException {
ParseQuery<ParseObject> query = ParseQuery.getQuery("AndroidStoreContent");
query.whereExists("appIcon");
List<ParseObject> ParseResult = query.find();
// Drawable array
appIconDrawable = new Drawable[ParseResult.size()];
for (i = 0; i < ParseResult.size(); i++) {
ParseFile pf = (ParseFile) ParseResult.get(i).get("appIcon");
startDownload(pf);
}
return appIconDrawable;
}
public void startDownload(ParseFile pf) {
new DownloadImageTask(this).execute(pf);
}
public class DownloadImageTask extends AsyncTask<ParseFile, Void, Drawable> {
private AsyncResponse ar;
DownloadImageTask(AsyncResponse ar) {
this.ar = ar;
}
#Override
protected Drawable doInBackground(ParseFile... pf) {
return fetchDrawable(pf[0]);
}
protected void onPostExecute(Drawable result) {
ar.processFinish(result);
}
public Drawable fetchDrawable(ParseFile pf) {
InputStream is;
try {
is = (InputStream) new URL(pf.getUrl()).getContent();
return Drawable.createFromStream(is,null);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
#Override
public void processFinish(Drawable d) {
appIconDrawable[i] = d; // i also tried testing appIconDrawable[1] = d and the app loaded with all blank images and then crashes
}
This is the interface, AsyncResponse:
public interface AsyncResponse {
void processFinish(Drawable d);
}
It seems like you need a bit of refactor...
You are expecting Drawable[] from queryAppIcon() but you will always get an empty set because you start the download which takes place in a separate thread to then update the return value.
You should be setting the Drawable to the ImageView from within processFinish.
Signs of things done wrong: Async methods such as downloading images should never have a return value.
UPDATE
Here is a very simple download AsyncTask but there are many checks, optimizations, etc. missing, like CACHE! Also, ImageView inside DownloadImageTask should be held by a WeakReference (Google it) otherwise it WILL leak your activity.
public class DownloadImageTask extends AsyncTask<String, Void, Drawable> {
private static final String TAG = DownloadImageTask.class.getSimpleName();
private ImageView mImageView;
DownloadImageTask(ImageView imageView) {
mImageView = imageView;
}
#Override
protected Drawable doInBackground(String... url) {
return fetchDrawable(url[0]);
}
#Override
protected void onPostExecute(Drawable result) {
if (result != null) {
mImageView.setImageDrawable(result);
} else {
Log.w(TAG, "Could download image!");
}
}
public static Drawable fetchDrawable(String url) {
Log.v(TAG, "Downloading: " + url);
InputStream is;
try {
is = (InputStream) new URL(url).getContent();
return Drawable.createFromStream(is, null);
} catch (MalformedURLException e) {
Log.e(TAG, e.getMessage(), e);
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
return null;
}
}
Adapter:
public class ImageDownloadAdapter extends ArrayAdapter<String>{
public ImageDownloadAdapter(Context context, String[] objects) {
super(context, R.layout.item_image_download, R.id.txt_url, objects);
}
#SuppressLint("NewApi")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
String url = getItem(position);
ImageView imageView = (ImageView) view.findViewById(R.id.img_download);
DownloadImageTask downloadImageTask = new DownloadImageTask(imageView);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
downloadImageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
} else {
downloadImageTask.execute(url);
}
return view;
}
}
Activity:
ListView listView = (ListView) findViewById(android.R.id.list);
listView.setAdapter(new ImageDownloadAdapter(this, new String[]{
"http://www.beautystat.com/site/wp-content/uploads/2011/02/happy-faces-small.jpg",
"http://www.ducthide.com/new_wallet_pics/happy_face.JPG"
}));
I know that the first you gonna this is... why the heck on the world you then use AsyncTask.
So here is my problem i am working on some Android app (API 7 for android 2.1 or higher) , and i am testing on emulator and everything was fine, so then i tested on HTC Sensation and it says NetworkOnMainThreadExeption!
I was downloading some pictures and then draw on the map.
So to solve this problem every (internet connection) in this case downloading the pictures i must put on AsyncTask to work.
So i need a method how to know when all pictures are done so i can start drawing..
I was trying so much and no result i have no idea. I got one solution with handler but if run on slower net i get nullpointer(because the pictures are not downloaded).
So please help me.
EDIT:
here is the idea:
Bitmap bubbleIcon ;
onCreate(){
...
// i am making call for Async
new ImgDown().execute(url);
//and then i calling functions and classes to draw with that picture bubbleIcon !
DrawOnMap(bubbleIcon);
}
//THIS IS ASYNC AND FOR EX. SUPPOSE I NEED TO DOWNLOAD THE PIC FIRST
class ImgDown extends AsyncTask<String, Void, Bitmap> {
private String url;
public ImgDown() {
}
#Override
protected Bitmap doInBackground(String... params) {
url = params[0];
try {
return getBitmapFromURL(url);
} catch (Exception err) {
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
bubbleIcon = result;
bubbleIcon = Bitmap
.createScaledBitmap(bubbleIcon, 70, 70, true);
}
public Bitmap getBitmapFromURL(String src) {
try {
Log.e("src", src);
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
// /tuka decode na slika vo pomalecuk kvalitet!
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
Bitmap myBitmap = BitmapFactory
.decodeStream(new FlushedInputStream(input));
Log.e("Bitmap", "returned");
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
Log.e("getBitmapFromURL", e.getMessage());
return null;
}
}
class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int byteValue = read();
if (byteValue < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
}
i hope now is more clear.
class OpenWorkTask extends AsyncTask {
#Override
protected Boolean doInBackground(String... params) {
// do something
return true;
}
#Override
protected void onPostExecute(Boolean result) {
// The results of the above method
// Processing the results here
myHandler.sendEmptyMessage(0);
}
}
Handler myHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
// calling to this function from other pleaces
// The notice call method of doing things
break;
default:
break;
}
}
};
You can write your own Delegate to delegate info about finishing the task, using OOP principles:
task_delegate.java
public interface TaskDelegate {
void TaskCompletionResult(String result);
}
main_activity.java
public class MainActivity extends Activity implements TaskDelegate {
//call this method when you need
private void startAsynctask() {
myAsyncTask = new MyAsyncTask(this);
myAsyncTask.execute();
}
//your code
#Override
public void TaskCompletionResult(String result) {
GetSomethingByResult(result);
}
}
my_asynctask.java
public class MyAsyncTask extends AsyncTask<Void, Integer, String> {
private TaskDelegate delegate;
protected MyAsyncTask(TaskDelegate delegate) {
this.delegate = delegate;
}
//your code
#Override
protected void onPostExecute(String result) {
delegate.TaskCompletionResult(result);
}
}
class openWorkTask extends AsyncTask<String, String, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
//do something
return true;
}
#Override
protected void onPostExecute(Boolean result) {
// The results of the above method
// Processing the results here
}
}
I would use a Progress Dialog if I were you. This way users can see that something is happening while the ASyncTask downloads the picture. On PostExecute, call a method from your main code that checks if the pictures are null. Remember you cannot update the UI in the doInBackground method so do any UI work in either onPreExecute or onPostExecute
private class DownloadPictures extends AsyncTask<String, Void, String>
{
ProgressDialog progressDialog;
#Override
protected String doInBackground(String... params)
{
//Download your pictures
return null;
}
#Override
protected void onPostExecute(String result)
{
progressDialog.cancel();
//Call your method that checks if the pictures were downloaded
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(
YourActivity.this);
progressDialog.setMessage("Downloading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected void onProgressUpdate(Void... values) {
// Do nothing
}
}
Here is my issue: I am downloading Images from a server async and organize them in an array such as Image[1] would b the equivalent of Image1 the reason why I need the array to be organized is that I am trying to have an image rotating in 360 angle. So when I download the images into the array it seems that it's not doing the job correctly. Any advice is super greatly appreciated.
public class tst extends Activity implements OnClickListener {
TextView t;
Button b1;
ImageView iV;
Bitmap bitmap = null;
Bitmap [] angles;
String stringAngle;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
angles = new Bitmap[13];
b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(this);
iV = (ImageView) findViewById(R.id.imageView1);
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.button1){
//Toast.makeText(getApplicationContext(), "ghjh", Toast.LENGTH_SHORT).show();
for(int i = 1 ; i<13 ; i++)
{
stringAngle = Integer.toString(i);
new DownloadImageTask()
.execute("http://www.sampleurl"
+stringAngle+".png");
}
iV.setImageBitmap(angles[7]);
}
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
protected void onPostExecute(Bitmap result) {
// Do something with bitmap eg:
for(int m = 1 ; m<13;m++)
{
angles[m] =(Bitmap) result;
}
}
}
private Bitmap loadImageFromNetwork(String url) {
try {
bitmap = BitmapFactory.decodeStream((InputStream) new URL(url)
.getContent());
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
in this case iV.setImageBitmap(angles[7]) always comes back with different results.