0

I'm building a list view android application. I want a message to be returned when a url is clicked from the list which is in an array telling the user if the site is offline or online. I am doing this by a quick ping which returns a Boolean value to say this. I am a java newbie and I know it is something to do with the way I am calling the pinUrl() method as when I remove said if statement from onListItemClick() the app does no crash.

Here is my MainActivity for reference:

package com.seven.webtools;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.annotation.SuppressLint;
import android.app.ListActivity;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

@SuppressLint("UseValueOf")
public class MainActivity extends ListActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Resources res = getResources();
    String[] Sites = res.getStringArray(R.array.Sites);
    setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,Sites));

}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    // Get the selected url
    super.onListItemClick(l, v, position, id);
    Object o = this.getListAdapter().getItem(position);
    String address = o.toString();

    //Ping the address
    String Status = "offline";
    if (MainActivity.pingUrl(address) == true){
        Status = "online";
    }

    //Return the result
    Toast.makeText(this, address + " is " + Status, Toast.LENGTH_LONG).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public static boolean pingUrl(final String address) {
     try {
      final URL url = new URL("http://" + address);
      final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
      urlConn.setConnectTimeout(1000 * 10); // mTimeout is in seconds
      final long startTime = System.currentTimeMillis();
      urlConn.connect();
      final long endTime = System.currentTimeMillis();
      if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
       System.out.println("Time (ms) : " + (endTime - startTime));
       System.out.println("Ping to "+address +" was success");
       return true;
      }
     } catch (final MalformedURLException e1) {
      e1.printStackTrace();
     } catch (final IOException e) {
      e.printStackTrace();
     }
     return false;
    }

}

Thank you very much if you can help me out :)

Samuel Barnes
  • 113
  • 10

3 Answers3

1

You should use either an AsyncTask or a Thread and Handler.

Here's an example of a Thread and Handler:

public class MainActivity extends ListActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Resources res = getResources();
        String[] Sites = res.getStringArray(R.array.Sites);
        setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,Sites));
    }

    // Here is where we create our Handler that will receive the Message from the thread.
    private Handler handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            StringBuilder str = new StringBuilder();
            str.append((String) msg.obj).append("\r\n");
            str.append("response:  " + msg.arg1).append("\r\n");
            str.append("time: " + msg.arg2).append("\r\n");

            System.out.println(str.toString());
        }
    };

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id)
    {
        super.onListItemClick(l, v, position, id);

        final String address = l.getItemAtPosition(position).toString();

        // We create a new thread and implements the Runnable interface
        new Thread(new Runnable()
        {
            public void run()
            {
                URL url;
                HttpURLConnection connection = null;

                try
                {
                    url = new URL(address);

                    connection = (HttpURLConnection) url.openConnection();
                    connection.setConnectTimeout(10 * 1000);
                    connection.setReadTimeout(10 * 1000);

                    long start = System.currentTimeMillis();

                    connection.connect();

                    int response = connection.getResponseCode();

                    long end = System.currentTimeMillis();

                    // Here we create a new Message to send to the Handler object on the Activity
                    //  Send the response code, ping time, and the address
                    Message msg = Message.obtain(handler);
                    msg.arg1 = response;
                    msg.arg2 = (int) (end - start);
                    msg.obj = address;
                    msg.sendToTarget();
                }
                catch(MalformedURLException e)
                {
                    e.printStackTrace();
                }
                catch(IOException e)
                {
                    e.printStackTrace();
                }
                finally
                {
                    connection.disconnect();
                }
            }
        }).start();
    }
}
mrres1
  • 1,147
  • 6
  • 10
  • That all looks to be exactly what I want I have checked through it several times but I still get the "App has stopped working" message when a list item is clicked :/ any ideas? – Samuel Barnes May 19 '13 at 21:31
  • Post the Stack Trace, or the last 5 lines up to the Exception – mrres1 May 19 '13 at 21:56
0

Take a look at your stack-trace, I think you may be getting a NetworkOnMaintThreadException because you're doing the HTTP connection on the Main/UI thread. Do it in a separate thread, perhaps by using an AsyncTask, then you should be fine.

soren.qvist
  • 7,376
  • 14
  • 62
  • 91
0

Which Android-Version are you using? The App may crash because you are doing a network call on the UI-Main-Thread, which means that the UI freezes during the network call. In older versions it works without getting an exception. Since Version 2.3.x(correct me if I'm wrong) you get the android.os.NetworkOnMainThreadException.

Take a look in this post for more information how to solve this problem: - How to fix android.os.NetworkOnMainThreadException?

Community
  • 1
  • 1
Woda
  • 153
  • 8