-2

I am working on a simple RSS Reader for Android. This is the code I have:

package com.example.rssreader;

public class MainActivity extends ListActivity {

List headlines;
List links;
static final int DIALOG_ERROR_CONNECTION = 1;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (!isOnline(this)) {
        showDialog(DIALOG_ERROR_CONNECTION);
    } else {

    // initializing instance variables
    headlines = new ArrayList();
    links = new ArrayList();

    try {
        URL url = new URL("http://feeds.pcworld.com/pcworld/latestnews");

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(false);
        XmlPullParser xpp = factory.newPullParser();

        // We will get the XML from an input stream
        xpp.setInput(getInputStream(url), "UTF_8");

        /* We will parse the XML content looking for the <title> tag which appears inside the <item> tag.
         * However, we should take in consideration that the rss feed name also is enclosed in a <title> tag.
         * As we know, every feed begins with these lines: <channel><title>Feed_Name</title>...
         * so we should skip the <title> tag which is a child of <channel> tag,
         * and take in consideration only <title> tag which is a child of <item>
         * 
         * In order to achieve this, we will make use of a boolean variable.
         */

        boolean insideItem = false;

        // Returns the type of current event: START_TAG, END_TAG, etc..
        int eventType = xpp.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            if (eventType == XmlPullParser.START_TAG) {

                if (xpp.getName().equalsIgnoreCase("item")) {
                    insideItem = true;
                } else if (xpp.getName().equalsIgnoreCase("title")) {
                    if (insideItem)
                        headlines.add(xpp.nextText()); // extract the headline
                } else if (xpp.getName().equalsIgnoreCase("link")) {
                    if (insideItem)
                        links.add(xpp.nextText()); // extract the link of article
                }
            } else if (eventType == XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")) {
                insideItem = false;
            }

            eventType = xpp.next(); // move to next element
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    // Binding data
    ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, headlines);

    setListAdapter(adapter);

    }
}

public InputStream getInputStream(URL url) {
    try {
        return url.openConnection().getInputStream();
    } catch (IOException e) {
        return null;
    }
}

public boolean isOnline(Context c) {
    ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo ni = cm.getActiveNetworkInfo();

    if(ni!=null && ni.isConnected())
        return true;
    else
        return false;
}

@Override
protected Dialog onCreateDialog(int id) {
    Dialog dialog = null;
    switch(id) {
    case DIALOG_ERROR_CONNECTION:
        AlertDialog.Builder errorDialog = new AlertDialog.Builder(this);
        errorDialog.setTitle("Error");
        errorDialog.setMessage("No internet connection.");
        errorDialog.setNeutralButton("OK", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int id) {
                dialog.dismiss();
            }
        });

        AlertDialog errorAlert = errorDialog.create();
        return errorAlert;

        default:
            break;
    }
    return dialog;
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    Uri uri = Uri.parse((String) links.get(position));
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}
}

I don't get any errors in the code, but when I try to launch it, it crashes. I can't figure out why though. This is my log:

09-19 09:49:18.207: E/AndroidRuntime(3360): FATAL EXCEPTION: main
09-19 09:49:18.207: E/AndroidRuntime(3360): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.rssreader/com.example.rssreader.MainActivity}: android.os.NetworkOnMainThreadException
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.app.ActivityThread.access$600(ActivityThread.java:127)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.os.Looper.loop(Looper.java:137)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.app.ActivityThread.main(ActivityThread.java:4441)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at java.lang.reflect.Method.invokeNative(Native Method)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at java.lang.reflect.Method.invoke(Method.java:511)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at dalvik.system.NativeStart.main(Native Method)
09-19 09:49:18.207: E/AndroidRuntime(3360): Caused by: android.os.NetworkOnMainThreadException
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1108)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.io.IoBridge.connectErrno(IoBridge.java:133)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.io.IoBridge.connect(IoBridge.java:118)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at java.net.Socket.connect(Socket.java:849)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:77)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpConnection.connect(HttpConnection.java:117)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpEngine.connect(HttpEngine.java:303)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at com.example.rssreader.MainActivity.getInputStream(MainActivity.java:108)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at com.example.rssreader.MainActivity.onCreate(MainActivity.java:57)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.app.Activity.performCreate(Activity.java:4465)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
09-19 09:49:18.207: E/AndroidRuntime(3360):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
09-19 09:49:18.207: E/AndroidRuntime(3360):     ... 11 more

I hope maybe some of you can help me out!

Zero
  • 1,864
  • 3
  • 21
  • 39

2 Answers2

3

There are two Solution of this Problem.

1) Don't write network call in Main UI Thread, Use Async Task for that.

2) Write below code into your MainActivity file after setContentView(R.layout.activity_main);

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}
Dipak Keshariya
  • 22,193
  • 18
  • 76
  • 128
0
Caused by: java.lang.SecurityException: ConnectivityService: Neither user 10111 nor current process has android.permission.ACCESS_NETWORK_STATE.

Add the permision:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Ahmad
  • 69,608
  • 17
  • 111
  • 137
  • Ok, I've implemented this solution but it still crashes. I've updated LogCat, so maybe you are willing to take a look at it? – Zero Sep 19 '12 at 07:48