Android RSS - Simple GridView - Show Headlines

android rss

Android RSS - Simple GridView - Show Headlines Tutorial.

XmlPullParser Overview

  • Is an interface, xmlPull.v1.XmlPullParser.
  • Added in API level 1;
  • Defines how to parse Xml documents.
  • Has two key methods : next() and nextToken();
  • We use XmlPullParserFactory to create its instance.
  • The method next() enables us work with higher level events while nextToken() at a lower level.
  • Invoking getEventType() enable us know the current state of event of the parser.
  • The first event state is _STARTDOCUMENT, calling next() moves us to the next event.
  • A couple of high level events accessible to next() include:
  1. START_TAG => Raised when XML start tag was read.
  2. TEXT => Raised when text content was read. The text itself can be retrieved using the getText()
  3. END_TAG => End tag was read.
  4. END_DOCUMENT => The very last event.

Lets proceed on to our example. Tutorial Points

  • We are parsing a wordpress news website RSS Feeds
  • We extract headlines and show in simple gridview.
  • Have a look at the video tutorial here to see the xml and website.

SECTION 1 : SETUP

Build.Gradle

  • Our dependencies.
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.tutorials.hp.simplegridviewrss"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
}

Our Manifest

  • Add internet connection permission.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorials.hp.simplegridviewrss">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

 SECTION 2 : NETWORK

Our Connector Class

  • Establish Connection for us.
  • We then make a HTTP GET request to server.
  • We use HttpURLConnection.
package com.tutorials.hp.simplegridviewrss.m_RSS;

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

public class Connector {

    public static Object connect(String urlAddress)
    {
        try {
            URL url=new URL(urlAddress);
            HttpURLConnection con= (HttpURLConnection) url.openConnection();

            //CONNECTION PROPERTIES
            con.setRequestMethod("GET");
            con.setConnectTimeout(15000);
            con.setReadTimeout(15000);
            con.setDoInput(true);

            return con;

        } catch (MalformedURLException e) {
            e.printStackTrace();
            return ErrorTracker.WRONG_URL_FORMAT;

        } catch (IOException e) {
            e.printStackTrace();
            return ErrorTracker.CONNECTION_ERROR;
        }
    }

}

Our RSS Downloader Class

  • Call connector to connect.
  • Subclasses AsyncTask.
  • Download data in background thread while showing progress dialog.
  • Calls Parser class to parse data when through.
package com.tutorials.hp.simplegridviewrss.m_RSS;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.GridView;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;

public class Downloader extends AsyncTask<Void,Void,Object> {

    Context c;
    String urlAddress;
    GridView gv;

    ProgressDialog pd;

    public Downloader(Context c, String urlAddress, GridView gv) {
        this.c = c;
        this.urlAddress = urlAddress;
        this.gv = gv;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd=new ProgressDialog(c);
        pd.setTitle("Fetch data");
        pd.setMessage("Fetching Data...Please wait");
        pd.show();

    }

    @Override
    protected Object doInBackground(Void... params) {
        return this.downloadData();
    }

    @Override
    protected void onPostExecute(Object data) {
        super.onPostExecute(data);
        pd.dismiss();
        if(data.toString().startsWith("Error"))
        {
            Toast.makeText(c,data.toString(),Toast.LENGTH_SHORT).show();
        }else {
            //CALL PARSER CLASS
            new RSSParser(c, (InputStream) data,gv).execute();
        }
    }

    private Object downloadData()
    {
        Object connection=Connector.connect(urlAddress);
        if(connection.toString().startsWith("Error"))
        {
            return connection.toString();
        }

        try
        {
            HttpURLConnection con= (HttpURLConnection) connection;
            InputStream is=new BufferedInputStream(con.getInputStream());

            return is;

        } catch (IOException e) {
            e.printStackTrace();
            return ErrorTracker.IO_EROR;
        }
    }
}

 SECTION 4 : RSS PARSING

Our RSS Parser Class

  • Receives data from Downloader class.
  • Parses this data using XmlPullParser.
  • Subclasses asynctask.
  • We parse in background thread using asynctask as well.
  • Sends the parsed data to adapter class for it be bound.
package com.tutorials.hp.simplegridviewrss.m_RSS;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.Toast;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

public class RSSParser extends AsyncTask<Void,Void,Boolean> {

    Context c;
    InputStream is;
    GridView gv;

    ProgressDialog pd;
    ArrayList<String> headlines=new ArrayList<>();

    public RSSParser(Context c, InputStream is, GridView gv) {
        this.c = c;
        this.is = is;
        this.gv = gv;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd=new ProgressDialog(c);
        pd.setTitle("Parse Data");
        pd.setMessage("Parsing...Please wait");
        pd.show();
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        return this.parseRSS();
    }

    @Override
    protected void onPostExecute(Boolean isParsed) {
        super.onPostExecute(isParsed);
        pd.dismiss();
        if(isParsed)
        {
            //BIND DATA
            gv.setAdapter(new ArrayAdapter<String>(c,android.R.layout.simple_list_item_1,headlines));

        }else {
            Toast.makeText(c,"Unable To Parse",Toast.LENGTH_SHORT).show();
        }
    }

    private Boolean parseRSS()
    {
        try
        {
            XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
            XmlPullParser parser=factory.newPullParser();

            //SET STREAM
            parser.setInput(is,null);
            String headline=null;

            int event=parser.getEventType();
            Boolean isWebsiteTiltle=true;

            do {
                String name=parser.getName();

                switch (event)
                {
                    case XmlPullParser.START_TAG:
                        break;

                    case XmlPullParser.TEXT:
                        headline=parser.getText();
                        break;

                    case XmlPullParser.END_TAG:

                        if(isWebsiteTiltle)
                        {
                            isWebsiteTiltle=false;
                        }else if(name.equals("title"))
                       {
                           headlines.add(headline);
                       }
                        break;
                }

                event=parser.next();

            }
            while (event != XmlPullParser.END_DOCUMENT);

            return true;

        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return false;
    }
}

SECTION 6 : MAIN ACTIVITY

Our MainActivity

  • Our launcher activity
  • Executes our downloader class on fab button click.
package com.tutorials.hp.simplegridviewrss;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.GridView;

import com.tutorials.hp.simplegridviewrss.m_RSS.Downloader;

public class MainActivity extends AppCompatActivity {

    final static String urlAddress="http://10.0.2.2/galacticnews/index.php/feed/";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);

        final GridView gv= (GridView) findViewById(R.id.gv);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                 new Downloader(MainActivity.this,urlAddress,gv).execute();
            }
        });
    }

}

SECTION 5 : LAYOUTS

ContentMain.xml

  • Contains our AdapterView.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.tutorials.hp.simplegridviewrss.MainActivity"
    tools:showIn="@layout/activity_main">

    <GridView
        android:id="@+id/gv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:numColumns="3" />
</RelativeLayout>

Android RSS Feeds GridView

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think


Previous Post Next Post