Как встроить RSS ленту в свое Android приложение, используя XML parser?

Программирование RSS parser в AndroidЕсли Вы читаете эту статью, то Вы вероятно знаете, что такое RSS и зачем оно используется. Если нет, посмотритездесь. С точки зрения программиста RSS лента представляет собой XML файл, который можно легко разобрать, используяXML parser. В распоряжении Android программиста находится довольно обширный набор библиотек для работы с XML

  •     javax.xml.parsers.SAXParser
  •     android.content.res.XmlResourceParser
  •     Простой API для работы с XML (SAX) в пакете org.xml.sax
  •     Android ROME Feed Reader - Google RSS ридер для Android
  •     Android Feed Reader - еще один Google RSS/Atom reader
  •     Android-rss - легкая библиотека для работы с RSS 2.0 лентами

Мы остановимся на первом варианте.SAXParserчасто используется при разработке Android приложений, поскольку он входит в состав Android SDK. В рамках этого небольшого урока мы создадим простое Android приложение и используем SAXParser для разбора и отображения ленты.

Создаем Android проект

Создадим простое приложение, которое будет получать RSS ленту. Для программирования будем использовать Eclipse IDE.

программирование android

  1. Выберите File->New->Project и в открывшемся диалоговом окне выбираем Android Project.
  2. В следующем диалоге в качестве имени проекта вводим RSSFeed, нажимаем кнопку Next.
  3. В следующем окне нам предлагают выбрать целевую платформу. Выбираем Android 2.3, нажимаем кнопку Next.
  4. Задаем в качестве имени приложения RSSFeed, в качестве названия пакета android.rss, помечаем флажком Create Activity и меняем стоящее рядом название на RssFeed. Minimum SDK устанавливаем в 10. Нажимаем кнопку Finish.

Обратите внимание, созданный нами класс RSSFeed, наследующий Activity фактически представляет собой визуальный пользовательский интерфейс - окно. Сейчас наш проект состоит из трех файлов:RSSFeed.java cодержит исходный код класса RSSFeed, файл разметкиres/layout/main.xml, содержащий информацию о дизайне пользовательского интерфейса и Android UI компонентах; файл манифеста AndroidManifest.xml, в котором хранится основные параметры проекта (название пакета, запускаемая при старте программы деятельность (Activity класс), компоненты приложения, процессы, разрешения, минимально необходимый уровень API). 

Давайте для начала настроим интерфейс нашего будущего приложения. Щелкнете два раза в дереве проекта по файлуres/layout/main.xml. В центральной части Eclipse откроется визуальный редактор. В моем случае на окне уже имеется компонент LinearLayout, у которого задана вертикальная ориентация. Под окном редактирования присутствует вкладка maix.xml, позволяющая переключиться от визуального редактора к редактору xml файла.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
</LinearLayout>

Android RSS парсинг


Мы хотим отображать ленту RSS как текстовое сообщение, поэтому нам понадобится разместить на экране элемент TextView, где мы будем отображать заголовок ленты. В поле android:text  мы видим значение "@string/hello". Это ссылка на переменную hello, прописанную в файле res\values\strings.xml. щелкнем по этому файлу и для элемента с именем hello введем значение "Наша RSS лента". Вернемся в main.xml и добавим еще один элемент TextView для отображение собственно ленты. Зададим параметр id "rss", как показано ниже

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <TextView android:id="@+id/rss"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Настройка AndroidManifest.xml

Мы будем получать RSS ленту с удаленного сервера, поэтому наше приложение должно иметь соответствующие разрешения. Щелкнем в дереве проектов по файлуAndroidManifest.xml, перейдем на вкладку Permissions, нажмем на кнопку Add, выберем Uses Permission, нажмем ОК. В поле Name введемandroid.permission.INTERNET. В результате этих действий в файле AndroidManifest.xml появится строка

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


После этого наше приложение может работать с сокетами и получать информацию из сети. Файл AndroidManifest.xml должен иметь вид:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.rss"
    android:versionCode="1"
    android:versionName="1.0" >

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".RSSFeed"
            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>

</manifest>


Парсинг RSS ленты в Android

Вся подготовительная работа сделана, настало время заняться тем, ради чего писалась данная статья - парсингом RSS ленты. Нам понадобится импортировать следующие классы:

  •     javax.xml.parsers.SAXParser
  •     javax.xml.parsers.SAXParserFactory
  •     org.xml.sax.InputSource
  •     org.xml.sax.XMLReader
  •     org.xml.sax.helpers.DefaultHandler

Вернемся в файл src\android.rss\RSSFeed.java и добавим в начало файла строки:

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

Внутри класса RSSFeed определим строковую переменную, куда будем загружать RSS ленту, перед заголовком метода onCreate.

 String rssResult = "";

Метод onCreate запускается при старте нашей программы. Сейчас этот метод содержит две строки, приводящие к отображению нашего окна на экране. Добавим в конец этого метода переменную rss, связанную со вторым элементом TextView. С помощью этой переменной мы будем отображать информацию на экране.

 TextView rss = (TextView) findViewById(R.id.rss);

 Метод findViewById позволяет найти элемент управления по его id (помните параметр android:id="@+id/rss", который мы задали у второго TextView, когда создавали дизайн).
 
 Загрузим из интернет RSS ленту, для этого воспользуемся классом URL, в конструкторе которого укажем адрес файла с лентой, напримерhttp://feeds2.feedburner.com/Mobilab (Да, у нас есть RSS лента, с помощью которой можно следить за новыми материалами на сайте). В процессе чтения может произойти ошибка ввода/вывода, поэтому Java требует помещать такие потенциально опасные команды в блок try/catch.

         try {
            URL rssUrl = new URL("http://feeds2.feedburner.com/Mobilab");
        } catch (IOException e) {rss.setText(e.getMessage());}

 Для того, чтобы программа заработала, нужно подключить еще парочку библиотек:

import android.widget.TextView;
import java.net.URL;
import java.io.IOException;

 Файл RSS ленты представляет собой XML, содержащий совокупность элементов <item>. Каждый <item> в свою очередь содержит внутри элементы title, description, link, creator,  date, названия которых говорят сами за себя.
 

 Создаем объект XML парсера

 Пользуясь статическим методом newInstance создадим объектSAXParserFactory

 SAXParserFactory factory = SAXParserFactory.newInstance();

 Создадим объект SAXParser с помощью newSAXParser:

 SAXParser saxParser = factory.newSAXParser();

 Получим объект XMLReader  от SAXParser с помощью метода getXMLReader:

 XMLReader xmlReader = saxParser.getXMLReader();

 Создание этих объектов требует размещение их в блоке try/catch и отработки исключительных ситуаций SAXException, ParserConfigurationException. Также нам понадобится подключить еще несколько библиотек

import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;

Обработка событий SAX2

Работа с SAXParser построена на обработке событий. При разборе XML файла  SAX2 генерирует события, например, при начале и завершении следующего элемента или блока символьных данных. Для обработки событий нужно создать специальный класс-потомок  DefaultHandler. Назовем его RSSHandler. Именно внутри этого класса будет происходить парсиг XML файла. Нам нужно переопределить методы startElement и  characters, отвечающие за начало нового элемента и считывание блока данных. Название элемента передается в startElement через параметр localName. Если мы встретили элемент <item>, мы должны добавить значение localName в строку результатов.

 rssResult = rssResult + localName + ": ";

 В методе characters будем добавлять символьные данные в строку rssResult. Метод replaceAll будем использовать для удаления всех двойных пробелов.

 String cdata = new String(ch, start, length);
    if (item == true)
    rssResult = rssResult +(cdata.trim()).replaceAll("\\s+", " ")+"\t";
   

Код класса приведен ниже

 private class RSSHandler extends DefaultHandler {

        public void startElement(String uri, String localName, String qName,
                Attributes attrs) throws SAXException {
            if (localName.equals("item"))
                item = true;

            if (!localName.equals("item") && item == true)
                rssResult = rssResult + localName + ": ";

        }

        public void endElement(String namespaceURI, String localName,
                String qName) throws SAXException {

        }

        public void characters(char[] ch, int start, int length)
                throws SAXException {
            String cdata = new String(ch, start, length);
            if (item == true)
                rssResult = rssResult +(cdata.trim()).replaceAll("\\s+", " ")+"\t";

        }

    }

 Да, нужно подключить библиотеку org.xml.sax.Attributes;

 Вернемся к методу onCreate. Создадим объект RSSHandler и передадим его объекту XMLReader с помощью метода setContentHandler. Тем самым мы говорим  XMLReader-у, что будем использовать методы RSSHandler при парсинге файла.

 RSSHandler rssHandler = new RSSHandler();
 xmlReader.setContentHandler(rssHandler);

В данный момент мы установили связь с удаленной страницей с помощью объекта URL, для считывания потока данных требуется создать объект InputSource и открыть поток данных для чтения с помощью метода openStream():

 InputSource inputSource = new InputSource(rssUrl.openStream());

 Созданный таким образом объект мы передаем XMLReader для разбора данных

 xmlReader.parse(inputSource);

 После этой команды происходит считывание и парсинг файла файла RSS ленты, в процессе которого внутри методов класса RSSHandler заполняется данными строка rssResult. Все что нам осталось, передать текст из этой строки в элемент TextView на экране.

 rss.setText(rssResult);

 Вот, собственно и все. Мы считали удаленный файл, провели его разбор, в процессе которого сформировали строку rssResult, а затем отобразили эту строку на экране с помощью TextView.
 
 Ниже приведен полный листинг файла RSSFeed.java

 package android.rss;

import android.app.Activity;
import android.os.Bundle;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import android.widget.TextView;
import java.net.URL;
import java.io.IOException;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.Attributes;

public class RSSFeed extends Activity {
    /** Called when the activity is first created. */
    String rssResult = "";
    boolean item = false;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView rss = (TextView) findViewById(R.id.rss);
        try {
            URL rssUrl = new URL("http://feeds2.feedburner.com/Mobilab");
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
            XMLReader xmlReader = saxParser.getXMLReader();           
            RSSHandler rssHandler = new RSSHandler();
            xmlReader.setContentHandler(rssHandler);
            InputSource inputSource = new InputSource(rssUrl.openStream());
            xmlReader.parse(inputSource);
            rss.setText(rssResult);
        } catch (IOException e) {rss.setText(e.getMessage());
        } catch (SAXException e) {rss.setText(e.getMessage());
        } catch (ParserConfigurationException e) {rss.setText(e.getMessage());
        }
    }
   
    private class RSSHandler extends DefaultHandler {

        public void startElement(String uri, String localName, String qName,
Attributes attrs) throws SAXException {
            if (localName.equals("item"))
                item = true;

            if (!localName.equals("item") && item == true)
                rssResult = rssResult + localName + ": ";

        }

        public void endElement(String namespaceURI, String localName,
String qName) throws SAXException {

        }

        public void characters(char[] ch, int start, int length)
                throws SAXException {
            String cdata = new String(ch, start, length);
            if (item == true)
                rssResult = rssResult +(cdata.trim()).replaceAll("\\s+", " ")+"\t";

        }

    }
       
}

Источник:Javaworld.com
Автор:Deepak Vohra
Перевод:Александр Ледков




Наши соцсети

Подписаться Facebook Подписаться Вконтакте Подписаться Twitter Подписаться Google Подписаться Telegram

Популярное

Ссылки

Новости [1] [2] [3]... Android/ iOS/ J2ME[1] [2] [3]) Android / Архив

Рейтинг@Mail.ru Яндекс.Метрика
MobiLab.ru © 2005-2018
При использовании материалов сайта ссылка на www.mobilab.ru обязательна