Grabbing a pic from URL - android

I just wanted to Grab an image from a URL and to display it in an imageview
The code:
public class MainActivity extends Activity {
// declare internal using controls
private TextView txtUrl;
private ImageView imgView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgView =(ImageView)findViewById(R.id.imageView1);
Drawable drawable=null;
drawable = grabImageFromUrl("http://blog.sptechnolab.com/wp-content/uploads/2011/02/c2.jpg");
imgView.setImageDrawable(drawable);
}
private Drawable grabImageFromUrl(String url) {
try {
return Drawable.createFromStream((InputStream)new URL(url).getContent(), "src");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
I am having this error:
09-04 20:34:18.712: E/AndroidRuntime(1156): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.MainActivity}: android.os.NetworkOnMainThreadException
I would appreciate your help please be specific in your answers

Is your app configured with Internet permissions? That is, do you have the following in your app's manifest?
<uses-permission android:name="android.permission.INTERNET" />
FOLLOW UP: Also, the error seems to be saying you shouldn't do network access on your app's UI thread. It's generally a bad practice to do any long blocking I\O on your app's UI thread. Try using an AnycTask, or you might even have a look at some of the code in LazyList.
EXAMPLE: add this as an inner class to your activity:
private class DownloadTask extends AsyncTask<Void, Void, Drawable>{
private final String mUrl;
public DownloadTask(String url){
mUrl = url;
}
#Override
protected Drawable doInBackground(Void... params) {
try {
return Drawable.createFromStream((InputStream)new URL(mUrl).getContent(), "src");
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(Drawable result){
((ImageView)findViewById(R.id.imageView1)).setImageDrawable(result);
}
}
Then call it like this from your onCreate:
new DownloadTask(url).execute();

Take a look at this question in stack also :
Display image from URL - sizing and screen orientation problems
It could be helpful.

The easy way is to simply use setImageURI:
imgView = (ImageView)findViewById(R.id.imageView1);
imgView.setImageURI(Uri.parse("http://blog.sptechnolab.com/wp-content/uploads/2011/02/c2.jpg"));
As noted in the docs though:
This does Bitmap reading and decoding on the UI thread, which can cause a latency hiccup.
If that's a concern, you probably want to decode in an AsyncTask as suggested by another answer.

Related

android Asynctask thread.sleep?

In my app when user writes wrong character,my edittext becomes red then it becomes write.Actually ı am trying to make a red blink.This is my working code
class BlinkTask extends AsyncTask<EditText, Boolean, Boolean>
{
#Override
protected Boolean doInBackground(EditText... params) {
EditText et1=params[0];
try {
et1.setBackgroundColor(Color.RED);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
et1.setBackgroundColor(Color.WHITE);
}
catch (Exception e)
{
e.printStackTrace();
}
return true;
}
}
but when I take et1.setBackgroundColor(Color.WHITE); out of try-catch block.It gives no error but unfortunately myapp has stopped.I checked loggat but saw nothing.this is false code
class BlinkTask extends AsyncTask
{
#Override
protected Boolean doInBackground(EditText... params) {
EditText et1=params[0];
try {
et1.setBackgroundColor(Color.RED);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
et1.setBackgroundColor(Color.WHITE);
return true;
}
}
I don't know why it needs try-catch although it gives no error.
also ı want to ask creating a asynctask class for this task is a good solution or nwhat else can be done.thank you
You should use animations for this purpose.
AsyncTask does not run on the UI thread so it cannot touch UI components. But there is a trick to do so.
class BlinkTask extends AsyncTask<EditText, Integer, Boolean>
{
private EditText et1;
#Override
protected Boolean doInBackground(EditText... params) {
et1 = params[0];
try {
publishProgress(Color.RED);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
publishProgress(Color.WHITE);
}
catch (Exception e)
{
e.printStackTrace();
}
return true;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
et1.setBackgroundColor(values[0]);
}
}
But to be honest, changing a background color of edittext in an asynctask is a bad idea. Use should take a look at animations.
I think because you now are in a different thread of main thread and edit text is one element of UIthread then you must use your code inside UIthread.
you can search for "how to use runonUIthread in java android".
hope this help you.

JSoup not working in android

I am creating an app to fetch XKCD comics (just for learning purpose). I am using JSoup to fetch comic title and url of the image and Universal Image Loader to post the image in ImageView. However I'm facing some problems. Here is my main activity.
public class MainActivity extends Activity {
private static final String TAG = "MyApp";
ImageView xkcdImgIV;
TextView titleTV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
xkcdImgIV=(ImageView) findViewById(R.id.xkcdImgIV);
titleTV=(TextView) findViewById(R.id.titleTV);
try{
new AsyncImg().execute(new String[]{"http://www.xkcd.com/"});
} catch(NullPointerException e){
Log.d(TAG,"Null pointer exception")
}
}
private class AsyncImg extends AsyncTask<String,Void,Void>{
Document doc;
Elements elXkcdTitle;
Elements elXkcdImgUrl;
#Override
protected Void doInBackground(String... arg) {
try {
doc = Jsoup.connect(arg[0]).timeout(0).get();
elXkcdTitle=doc.select("#ctitle");
elXkcdImgUrl=doc.select("#comic img");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result) {
titleTV.setText(elXkcdTitle.first().text());
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.init( ImageLoaderConfiguration.createDefault(getApplicationContext() ));
imageLoader.displayImage(elXkcdImgUrl.first().attr("src"), xkcdImgIV);
}
}
}
There is no network activity. I've given the Internet access permission to the app. Moreover Logcat doesn't show any error. Both Jsoup and Universal Image Loader JARS have been included in build path. Feel free to ask for additional info.

Android AsyncTask change

Why, when I change
private class DownloadTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
try {
Downloader.DownloadFromUrl("http://www.sciencemag.org/rss/news.xml", openFileOutput("Sciencemag.xml", Context.MODE_PRIVATE));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result){
mAdapter = new SiteAdapter(MainActivity.this, -1, XmlParser.getSingleItemsFromFile(MainActivity.this));
sitesList.setAdapter(mAdapter);
}
}
to
private void downloadFile(){
try {
Downloader.DownloadFromUrl("http://www.sciencemag.org/rss/news.xml", openFileOutput("Sciencemag.xml", Context.MODE_PRIVATE));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
mAdapter = new SiteAdapter(MainActivity.this, -1, XmlParser.getSingleItemsFromFile(MainActivity.this));
sitesList.setAdapter(mAdapter);
}
i get an error? I just want to call method downloadFile() instead of creating instance of inner class DownloadTask and call execute() of this instance.
The error is telling you that you cannot make network tasks on the main thread.
Look at the Android API where NetworkOnMainThreadException is defined to know more about it.
I hope this helps!
Imagine your method downloadFile() takes too long time - this will block the UI. To prevent this you should use AsyncTask which will do the background operations (downloading your file i guess) and when it is ready will update your UI. In doInBackground() put your downloadFile() method and in onPostExecute() deal with the result. Also be careful what parameters to give to your AsyncTask class.

Handle AsyncTask in Class

I am using AsyncTask Class to handle images that are coming from the server to display it in the ImageView I have one Next button in my code to call the next image using following code:
private class LoadImage extends AsyncTask<Void, Void, Void> {
#Override
protected void onPostExecute(Void result) {
if (imgque != null) {
imgSelectedQue.setImageDrawable(imgque);
if (getActivity() != null) {
adjustResourceEnvelope();
}
}
}
#Override
protected void onPreExecute() {
imgque = null;
imgSelectedQue.setImageDrawable(null);
imgSelectedQue.requestLayout();
}
#SuppressWarnings("deprecation")
#Override
protected Void doInBackground(Void... params) {
InputStream is;
try {
is = (InputStream) new URL(Constants.PLAYER_SERVICE_BASE_URL + "/playerservice"
+ imageurl).getContent();
imgque = Drawable.createFromStream(is, null);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
imgque = null;
e.printStackTrace();
}
return null;
}
}
Now the issue is that if I click the next button REPEATEDLY then it call the AsyncTask that many times and ImageView displaying all the images like "Slide-Show" because all the url images are in queue.
Is there any way to display only last AsyncTask call image?
Do something like this:
[1] When you call LoadImage AsyncTask on click of NEXT button disable NEXT button.
[2] On onPreExecute() method of your LoadImage AsyncTask enable your NEXT button again.
OR,
You can achieve such things with use of simple FLAG also. By setting it as true and false.
Hope this helps you.
Thanks.
I Found the Solution for this.If anyone facing the same issue.
I Added new lines
if (loadimage != null)
{
loadimage.cancel(true);
loadimage = null;
}
loadimage.cancel(true) will stop the AsyncTask if it is already Running
then execute the AsycTask()
loadimage = new LoadImage();
loadimage.execute();
In this way i am able to call only last AsyncTask that what I required.

How to send an image from background thread to the UI thread using AsyncTask?

I'm using AsyncTask to download an image and want to send the downloaded image to the UI thread. Here is the code for it.
public class DownloadImageTask extends AsyncTask<URL, Void, Drawable>{
#Override
protected Drawable doInBackground(URL... imgURL) {
// TODO Auto-generated method stub
InputStream in;
Bitmap bitmap;
Drawable d;
try {
//in = (InputStream) imgURL[0].getContent();
bitmap = BitmapFactory.decodeStream(imgURL[0].openConnection().getInputStream());
d =(Drawable)new BitmapDrawable(bitmap);
return d;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
Thanks.
After doInBackround() is executed the returned value will be passed to onPostExecute() in your AsynkTask, so you should override the onPostExecute() method, and there you will receive your Drawable. Note that onPostExecute() and onPreExecute() are run on the UI Thread so you are able to modify/update the UI from this 2 methods.
class DownloadTask extends AsyncTask
{
#Override
protected Boolean doInBackground(Url... url) {
Bitmap b =
// do some bitmap downloader code from web url
return b;
}
#Override
protected void onPostExecute(Bitmap image) {
imageView.setImageBitmap(image);
}
}
chek out this code because U cannot set image from doInBackGround()....
But still if u want to set it there are 2 ways.
use OnProgressUpdate() method on this thread or
try method Activity.runOnUiThread(){} thro' which it will interact with UI thread

Categories

Resources