0

Possible Duplicate:
Download a file with Android, and showing the progress in a ProgressDialog

I am trying to load a image from a website,I saw this question : Android load from URL to Bitmap but my application crash at this line : conn.connect();

public class HTTPTest extends Activity {

ImageView imView;
String imageUrl = "http://api.androidhive.info/images/sample.jpg";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    Button bt3 = (Button) findViewById(R.id.get_imagebt);
    bt3.setOnClickListener(getImgListener);
    imView = (ImageView) findViewById(R.id.imview);
}

View.OnClickListener getImgListener = new View.OnClickListener() {

    @Override
    public void onClick(View view) {
        // TODO Auto-generated method stub
        downloadFile(imageUrl);
    }
};

Bitmap bmImg;

void downloadFile(String fileUrl) {
    URL myFileUrl = null;
    try {
        myFileUrl = new URL(fileUrl);
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        HttpURLConnection conn = (HttpURLConnection) myFileUrl
                .openConnection();
        conn.setDoInput(true);
        conn.connect();
        InputStream is = conn.getInputStream();

        bmImg = BitmapFactory.decodeStream(is);
        imView.setImageBitmap(bmImg);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView  
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, HTTPImage load test"
/>
    <Button 
android:id="@+id/get_imagebt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get an image"
android:layout_gravity="center"
/>  
<ImageView 
android:id="@+id/imview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>

My manifest :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidtest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="16" />


<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.androidtest.HTTPTest"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<!-- Permission to write to external storage -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

Thanks in advance for you help!

Germain.

Community
  • 1
  • 1
GermainGum
  • 1,349
  • 3
  • 15
  • 40
  • I can only guess that the exception is NetworkOnMainThread... – Sam Nov 19 '12 at 23:09
  • oh yes indeed. How can I fix that? My catlog: 11-19 15:12:52.655: E/AndroidRuntime(21823): FATAL EXCEPTION: main 11-19 15:12:52.655: E/AndroidRuntime(21823): android.os.NetworkOnMainThreadException 11-19 15:12:52.655: E/AndroidRuntime(21823): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1178) .. – GermainGum Nov 19 '12 at 23:15
  • In the future always add your LogCat to your question whenever the app crashes, it is the road map to help us solve your error. – Sam Nov 19 '12 at 23:20
  • Ok I will thanks for your answers, I am looking at your link/url right now – GermainGum Nov 19 '12 at 23:28
  • I posted a solution for your new error. – Sam Nov 20 '12 at 00:34

2 Answers2

3

You should run all network requests on another thread (i.e not on the UI Thread). In fact Android makes you do this. Otherwise your UI will lock while you are waiting for a response. Change your downloadFile() method to look like this. An AsyncTask will run your code on another thread. A good practice for tasks that will take a while to execute.

void downloadFile(String fileUrl) {

    AsyncTask<String, Object, String> task = new AsyncTask<String, Object, String>() {

        @Override
        protected String doInBackground(String... params) {
            URL myFileUrl = null;
            try {
                myFileUrl = new URL(params[0]);
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                HttpURLConnection conn = (HttpURLConnection) myFileUrl
                        .openConnection();
                conn.setDoInput(true);
                conn.connect();
                InputStream is = conn.getInputStream();

                bmImg = BitmapFactory.decodeStream(is);
                imView.setImageBitmap(bmImg);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return null;
        }
    };
    task.execute(fileUrl);

}
Jimbo
  • 156
  • 1
  • 3
  • You can only run an instance of an AsyncTask once. "The task can be executed only once (an exception will be thrown if a second execution is attempted.)" http://developer.android.com/reference/android/os/AsyncTask.html – Jimbo Nov 19 '12 at 23:30
  • I tried this but I have this error : 11-19 15:43:52.620: E/AndroidRuntime(23369): FATAL EXCEPTION: AsyncTask #1 11-19 15:43:52.620: E/AndroidRuntime(23369): java.lang.RuntimeException: An error occured while executing doInBackground() 11-19 15:43:52.620: E/AndroidRuntime(23369): at android.os.AsyncTask$3.done(AsyncTask.java:278) 11-19 15:43:52.620: E/AndroidRuntime(23369): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)... – GermainGum Nov 19 '12 at 23:45
  • can you post the full stacktrace? – Jimbo Nov 20 '12 at 00:02
  • Sorry I was disconnected from internet. The error was at this line : imView.setImageBitmap(bmImg); Sam gave me the solution. Thanks for your help Jimbo! – GermainGum Nov 20 '12 at 02:13
2

but my application crash at this line : conn.connect();

As of Android 3+ you cannot perform potentially slow network operations of the main thread.

Download the image in an AsyncTask so that it won't slow down the user's experience. Simply move your downloadFile() method into the doInBackground() method of an AsyncTask.

There is a very extensive answer here if you need detailed specifics.


Addition
Using Jimbo's doInBackground() you are probably getting an error from attempting to access the UI from a different thread, which you cannot do. You can override onPostExecute() in your AsyncTask to work with your Views since it has access to the UI thread:

@Override
protected void onPostExecute(String unused) {
    imView.setImageBitmap(bmImg);
}
Community
  • 1
  • 1
Sam
  • 86,580
  • 20
  • 181
  • 179