RSS新聞閱讀器

1.RSS格式結構php

http://rss.sina.com.cn/blog/tech/kj.xmlhtml

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" title="XSL Formatting" href="/show_new_final.xsl" media="all"?>
<!--
SINA Corporation (NASDAQ: SINA) is a leading online media company and value-added information service (VAS) provider for China and for Chinese communities worldwide. With a branded network of localized websites targeting Greater China and overseas Chinese, SINA provides services through five major business lines including SINA.com (online news and content), SINA Mobile (mobile value-added services), SINA Online (community-based services and games), SINA.net (search and enterprise services) and SINA E-commerce (online shopping), offering Internet users and government and business clients an array of services including online media and entertainment, online fee-based VAS/wireless VAS, and e-commerce and enterprise e-solutions.
With 230 million registered users worldwide, 450 million daily page views and over 60 million active users for a variety of fee-based services, SINA is the most recognized Internet brand name in China and among Chinese communities globally.
In various surveys and polls, SINA has been recognized as the most valuable brand and the most popular website in China. For 2003 and 2005, SINA was ranked the "Most Preferred Website" in China according to the Chinese Academy of Social Sciences and considered "The Most Respected Chinese Company" for three consecutive years in 2003, 2004 and 2005 by the Economic Observer and the Management Case Study Center of Beijing University. At the same time, South China Weekend in both 2003 and 2004 honored SINA with the prestigious award of the "Chinese Language Medium of the Year."
****[pid:346,tid:121,did:20,fid:3468]****-->
<rss version="2.0">
    <channel>
        <title>
            <![CDATA[IT-新浪博客]]>
        </title>
        <image>
            <title>
                <![CDATA[新浪博客頻道]]>
            </title>
            <link>http://blog.sina.com.cn</link>
            <url>http://www.sinaimg.cn/blog/main/index2010/blog_logo.png</url>
        </image>
        <description>
            <![CDATA[IT博客列表]]>
        </description>
        <link>http://blog.sina.com.cn/lm/tech/</link>
        <language>zh-cn</language>
        <generator>WWW.SINA.COM.CN</generator>
        <ttl>5</ttl>
        <copyright>
            <![CDATA[Copyright 1996 - 2013 SINA Inc. All Rights Reserved]]>
        </copyright>
        <pubDate>Mon, 18 Nov 2013 07:39:30 GMT</pubDate>
        <category>
            <![CDATA[]]>
        </category>
        <item>
            <title>
                <![CDATA[案例解讀:電商企業如何作出差別]]>
            </title>
            <link>http://go.rss.sina.com.cn/redirect.php?url=http://blog.sina.com.cn/s/blog_6f3c35310101qkhr.html</link>
            <author>WWW.SINA.COM.CN</author>
            <guid>http://go.rss.sina.com.cn/redirect.php?url=http://blog.sina.com.cn/s/blog_6f3c35310101qkhr.html</guid>
            <category>
                <![CDATA[IT博客]]>
            </category>
            <pubDate>Mon, 18 Nov 2013 06:53:46 GMT</pubDate>
            <comments></comments>
            <description>
                <![CDATA[]]>
            </description>
        </item>
        <item>
            <title>
                <![CDATA[iOS 7:時尚與易用的平衡]]>
            </title>
            <link>http://go.rss.sina.com.cn/redirect.php?url=http://blog.sina.com.cn/s/blog_604f5cca0102e5tr.html</link>
            <author>WWW.SINA.COM.CN</author>
            <guid>http://go.rss.sina.com.cn/redirect.php?url=http://blog.sina.com.cn/s/blog_604f5cca0102e5tr.html</guid>
            <category>
                <![CDATA[IT博客]]>
            </category>
            <pubDate>Mon, 18 Nov 2013 06:40:45 GMT</pubDate>
            <comments></comments>
            <description>
                <![CDATA[]]>
            </description>
        </item>
    </channel>
</rss>

2.登陸java

界面:android

Screenshot_2013-11-18-17-18-29

login.xmlweb

<?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"
    >
    <!-- 登錄圖片 -->
    <ImageView
        android:id="@+id/login_rss"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/rss"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="30dp"
        />    
    <!-- 登錄文本 -->
    <TextView
        android:id="@+id/logining"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="@string/logining"
        android:visibility="invisible"
        android:layout_marginTop="20dp"
        />
    <!-- 登錄按鈕 -->
    <Button
        android:id="@+id/login_in"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="@string/login_in"
        android:layout_marginTop="10dp"
        />
</LinearLayout>

loginActivity.java sql

package com.rss.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class LoginActivity extends Activity {
    //登錄按鈕
    private Button loginButton;
    //登錄文本
    private TextView loginText;
    //登錄圖片
    private ImageView imagView;
    //圖片透明度
    private int i_alpha = 255;
    private Handler mHandler = new Handler();
    boolean isShow = false;
    private Thread thread;
    private Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        //初始化界面元素
        loginButton = (Button)findViewById(R.id.login_in);
        loginText = (TextView)findViewById(R.id.logining);        
        imagView = (ImageView)findViewById(R.id.login_rss);
        //初始化圖片分辨率
        imagView.setAlpha(i_alpha);
        isShow = true;            
        //更改圖片分辨率
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {                
                super.handleMessage(msg);
                imagView.setAlpha(i_alpha);
            }            
        };
        
        //開啓線程每隔100ms更新一次圖片透明度
        thread = new Thread(new Runnable() {        
            public void run() {
                while(isShow) {
                    try {
                        Thread.sleep(100);
                        updateAlpha();                        
                    }catch (InterruptedException  e) {
                        e.printStackTrace();
                    }
                }                
            }
            
        });            
        //登錄按鍵監聽器
        loginButton.setOnClickListener(new OnClickListener() {            
            public void onClick(View v) {
                intent = new Intent();
                intent.setClass(LoginActivity.this, SelectChannel.class);
                //啓動線程
                thread.start();            
                //設置登錄按鈕不可見
                loginButton.setVisibility(View.INVISIBLE);
                //設置登錄文本顯示
                loginText.setVisibility(View.VISIBLE);                
            }
        });
    }
    //更新圖片透明度
    protected void updateAlpha() {
        //每次減25
        if((i_alpha-25) >= 0) {
            i_alpha = i_alpha - 25;        
            
        }else {
            //當透明度低於25,關閉當前界面,啓動新界面
            i_alpha = 0;
            isShow = false;
            startActivity(intent);    
            LoginActivity.this.finish();
        }        
        //傳遞消息
        mHandler.sendMessage(mHandler.obtainMessage()); 
    }
}

3.數據庫存儲數據庫

RSSProvider.java數組

package com.rss.db;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
//Rss數據內容管理
public class RssProvider extends ContentProvider {
    //rss內容數據庫文件名
    private static final String RSS_DATABASE = "rss.db";
    //數據庫表名
    private static final String RSS_TABLE = "rss_item";
    private static final int RSS_DATABASE_VERSION = 1;    
    private static final String TAG = "RssProvider";    
    //URI
    public static final Uri RSS_URI = Uri.parse("content://com.rss.activity/rss");
    
    //列名
    public static final String RSS_ID = "_id";
    public static final String RSS_TITLE = "title";
    public static final String RSS_DESCRIPTION = "description";
    public static final String RSS_LINK = "link";
    public static final String RSS_PUBDATE = "pubDate";
    
    //列的索引
    public static final int TITLE_INDEX = 1;
    public static final int DESCRIPTION_INDEX = 2;
    public static final int LINK_INDEX = 3;
    public static final int PUBDATE_INDEX = 4;
    
    //建立表的sql語句
    private static final String RSS_SQL = "CREATE TABLE " + RSS_TABLE + "("
                + RSS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + RSS_TITLE + " TEXT, "
                + RSS_DESCRIPTION + " TEXT, "
                + RSS_LINK + " TEXT, "
                + RSS_PUBDATE + " DATE);";
    
    SQLiteDatabase rssDb = null;
    
    //建立用來區分不一樣URI的常量
    private static final int RSS = 1;
    private static final int RSSID = 2;
    //uri地址匹配器
    private static UriMatcher uriMatcher;    
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.rss.activity", "rss", RSS);
        uriMatcher.addURI("com.rss.activity", "rss/#", RSSID);
    }
    //建立管理數據的helper類
    private static class RssDatabaseHelper extends SQLiteOpenHelper {
        //構造函數
        public RssDatabaseHelper(Context context) {
            super(context, RSS_DATABASE, null, RSS_DATABASE_VERSION);
            Log.v(TAG, "Rss database create successfully!");
        }
        //第一次建立數據庫時調用
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(RSS_SQL);    
            Log.v(TAG, "Rss table create successfully!");
        }
        //升級時調用
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + RSS_TABLE);
            onCreate(db);//從新建立表            
        }
        
    }    
    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {        
        return 0;
    }
    //取得uri地址對應的操做
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
        case RSS:
            return "vnd.android.cursor.dir/com.rss.activity";
        case RSSID:
            return "vnd.android.cursor.item/com.rss.activity";
        default:
            throw new IllegalArgumentException("Unsupport URI:" + uri);
        }
    }
    //存儲數據
    @Override
    public Uri insert(Uri _uri, ContentValues values) {
        Uri uri = null;
        long rowId = rssDb.insert(RSS_TABLE, null, values);
        //返回的rowId > 0
        if(rowId > 0) {
            uri = ContentUris.withAppendedId(RSS_URI, rowId);
            getContext().getContentResolver().notifyChange(uri, null);
        }
        return uri;
    }
    //初始化函數
    @Override
    public boolean onCreate() {
        Context context = getContext();
        //實例化數據庫幫助類
        RssDatabaseHelper rssDbHelper = new RssDatabaseHelper(context);
        //得到對應的是數據庫
        rssDb = rssDbHelper.getWritableDatabase();        
        return (rssDb == null) ? false : true;
    }
    //查詢
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder sqb = new SQLiteQueryBuilder();
        sqb.setTables(RSS_TABLE);//設置查詢的表
        //篩選uri地址
        switch (uriMatcher.match(uri)) {
        //查詢單個RSS信息
        case RSSID:
            sqb.appendWhere(RSS_ID + "=" + uri.getPathSegments().get(1));            
            break;
        default:
            break;
        }
        String orderBy;        
        if(TextUtils.isEmpty(sortOrder)) {
            orderBy = RSS_PUBDATE;
        }else {
            orderBy = sortOrder;
        }        
        //對底層數據庫的應用查詢
        Cursor c = sqb.query(rssDb, projection, selection, selectionArgs, null, null, orderBy);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }
    //更新數據
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        int count;
        //匹配uri地址
        switch (uriMatcher.match(uri)) {
        case RSS:
            count = rssDb.update(RSS_TABLE, values, selection, selectionArgs);
            break;
        case RSSID:
            String segment = uri.getPathSegments().get(1);
            count = rssDb.update(RSS_TABLE, values, RSS_ID + "=" + segment
                    + (!TextUtils.isEmpty(selection) ? " AND ("
                    + selection +')' : ""), selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unkown URI " + uri);
        }
        //通知更改
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
}

ChannelDataHelper.java瀏覽器

package com.rss.data;

import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
//RSS數據庫操做類
public class ChannelDataHelper {
        //數據庫名稱  
        private static String DB_NAME = "RssChannel.db";  
        //數據庫版本  
        private static int DB_VERSION = 1;  
        private SQLiteDatabase db;  
        private SqliteHelper dbHelper;  
        //構造函數
        public ChannelDataHelper(Context context){  
            //實例化數據庫幫組類
            dbHelper=new SqliteHelper(context,DB_NAME, null, DB_VERSION);  
            //得到當前數據庫
            db= dbHelper.getWritableDatabase();  
        }  
        //關閉數據庫 
        public void Close()  
        {  
            db.close();  
            dbHelper.close();  
        }  
        //獲取全部的RSS源信息 
        public List<String> GetChannelList()  
        {  
            List<String> ChannelList = new ArrayList<String>();  
            //得到數據表中的全部數據
            Cursor cursor=db.query(SqliteHelper.TB_NAME, null, null, null, null, null, ID+" DESC");  
            //將遊標移動到開始
            cursor.moveToFirst();  
            //循環遍歷整個數據庫
            while(!cursor.isAfterLast()&& (cursor.getString(1)!=null)){  
                //取得源標題信息
                String channel=cursor.getString(1); 
                //添加到數組
                ChannelList.add(channel);  
                //移動遊標到下一個元素
                cursor.moveToNext();  
            }  
            cursor.close();  
            return ChannelList;
        }  
        //經過url名稱得到RSS源url地址
        public String getUrlByChannel(String name)
        {
            Cursor cursor=db.query(SqliteHelper.TB_NAME, null, NAME+"=?", new String[]{name}, null, null, null);
            //將遊標移動到開始
            cursor.moveToFirst(); 
            if(!cursor.isAfterLast()&& (cursor.getString(1)!=null))
                    return cursor.getString(2);
            return null;
        }
        //添加記錄  
        public Long SaveChannelInfo(String name,String url)  
        {  
            ContentValues values = new ContentValues();  
            values.put(NAME, name);  
            values.put(URL, url);  
            //插入新紀錄
            Long id = db.insert(SqliteHelper.TB_NAME, null, values);  
            Log.e("SaveChannelInfo",id+"");  
            return id;
        }          
        //刪除指定channle的記錄  
        public int DelChannelInfo(String name){  
            int id= db.delete(SqliteHelper.TB_NAME, NAME +"='"+name+"'", null);  
            Log.e("DelChannelInfo",id+"");  
            return id;  
        }
        //數據表的列信息
    static String ID="id";
    static String NAME="name";
    static String URL="url";
    //數據庫幫助類
    class SqliteHelper extends SQLiteOpenHelper{  
        
        //用來保存   RSS頻道的表名      
        public static final String TB_NAME="channel";  
        public SqliteHelper(Context context, String name, CursorFactory factory, int version) {  
        super(context, name, factory, version);  
        }  
        //建立表  
        @Override  
        public void onCreate(SQLiteDatabase db) {  
            db.execSQL("CREATE TABLE IF NOT EXISTS "+  
            TB_NAME+"("+  
            ID+" integer primary key,"+  
            NAME+" varchar,"+  
            URL+" varchar"+
            ")"  
            );  
            Log.e("Database","onCreate");  
        }  
        //更新表  
        @Override  
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
            db.execSQL("DROP TABLE IF EXISTS " + TB_NAME);  
            onCreate(db);  
            Log.e("Database","onUpgrade");  
        } 
    }
}

 

RSSItem.javaapp

package com.rss.data;
//Rssitem信息,用於存放RSS的每個item
public class RssItem {
    public static final String TITLE = "title";
    public static final String PUBDATE = "pubDate";
    //標題
    private String title;
    //詳細內容
    private String description;
    //連接
    private String link;
    //來源
    private String source;
    //日期
    private String pubDate;
    //得到標題
    public String getTitle() {
        return title;
    }
    //設置 標題
    public void setTitle(String title) {
        this.title = title;
    }
    //取得詳細信息
    public String getDescription() {
        return description;
    }
    //設置詳細信息
    public void setDescription(String description) {
        this.description = description;
    }
    //取得連接
    public String getLink() {
        return link;
    }
    //設置連接
    public void setLink(String link) {
        this.link = link;
    }
    //取得來源
    public String getSource() {
        return source;
    }
    //設置來源
    public void setSource(String source) {
        this.source = source;
    }
    //取得日期
    public String getPubDate() {
        return pubDate;
    }
    //設置日期
    public void setPubDate(String pubDate) {
        this.pubDate = pubDate;
    }
    //轉化成string
    public String toString() {
        if(title.length() > 20) {
            return title.substring(0, 42) + "...";
        }else {
            return title;
        }
    }
    
}

 

RssFeed.java

package com.rss.data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

public class RssFeed {
    //標題
    private String title;
    //日期
    private String pubdate;
    //數量
    private int itemcount;
    //用於存放RSS信息的列表
    private List<RssItem> itemlist;    
    public RssFeed() {
        itemlist = new Vector<RssItem>(0);
    }
    //添加元素
    public int addItem(RssItem item) {
        itemlist.add(item);
        itemcount++;
        return itemcount;
    }    
    //取得元素
    public RssItem getItem(int location) {
        return itemlist.get(location);
    }
    //取得全部列表須要的信息,存儲到List
    public List getAllItemsForListView() {
        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
        int size = itemlist.size();
        for(int i=0; i<size; i++) {
            HashMap<String, Object> item = new HashMap<String, Object>();
            item.put(RssItem.TITLE, itemlist.get(i).getTitle());
            item.put(RssItem.PUBDATE, itemlist.get(i).getPubDate());
            data.add(item);
        }
        
        return data;
    }
    //取得標題
    public String getTitle() {
        return title;
    }
    //設置標題
    public void setTitle(String title) {
        this.title = title;
    }
    //取得日期
    public String getPubdate() {
        return pubdate;
    }
    //設置日期
    public void setPubdate(String pubdate) {
        this.pubdate = pubdate;
    }
    //取得數量
    public int getItemcount() {
        return itemcount;
    }
    //設置數量
    public void setItemcount(int itemcount) {
        this.itemcount = itemcount;
    }
    //得到信息數組
    public List<RssItem> getItemlist() {
        return itemlist;
    }
    //設置信息數組
    public void setItemlist(List<RssItem> itemlist) {
        this.itemlist = itemlist;
    }    
}

4.選擇頻道

Screenshot_2013-11-18-17-18-34

selectChannel.java

package com.rss.activity;

import java.util.ArrayList;
import java.util.List;
import com.rss.data.ChannelDataHelper;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
//RSS源選擇界面
public class SelectChannel extends ListActivity{
    //menu菜單的id
    private static final int MENU_ADD = Menu.FIRST;
    private static final int MENU_QUIT = MENU_ADD + 1;
    //RSS源適配器
    ChannelAdapter mAdapter;
    //RSS源數據庫類
    ChannelDataHelper mChannel;
    //RSS源數組
    List<String> channelList=new ArrayList<String>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mChannel=new ChannelDataHelper(this);
        //取得數據庫全部內容
        channelList=mChannel.GetChannelList();
        mAdapter=new ChannelAdapter(this);
        //數據庫無內容
        if(mAdapter.getCount() == 0)
            Toast.makeText(this, "還沒有添加任何頻道", Toast.LENGTH_SHORT).show();
        setTitle("頻道選擇");
        //設置適配器
        setListAdapter(mAdapter);
        
    }
    //ListView是適配器
    class ChannelAdapter extends BaseAdapter  {
        private LayoutInflater mInflator;
        //構造函數
        public ChannelAdapter(Context context) {
            this.mInflator = LayoutInflater.from(context);
        }
        //取得數組大小
        public int getCount() {
            return channelList.size();
        }
        //取得當前位置的元素
        public String getItem(int position) {
            return channelList.get(position);
        }
        //取得當前位置的id
        public long getItemId(int position) {
            return 0;
        }
        //取得當前位置的視圖
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder vRss = null;
            //記錄當前的位置
            final int row = position;
            //初始化界面元素類
            vRss = new ViewHolder();
            //膨脹出界面
            convertView = mInflator.inflate(R.layout.item, null);
            //取得界面元素
            vRss.textLayout=(LinearLayout)convertView.findViewById(R.id.textLayout);    
            vRss.channel = (TextView)convertView.findViewById(R.id.title);    
            //設置標題字體大小
            vRss.channel.setTextSize(25);
            vRss.delBtn = (Button)convertView.findViewById(R.id.del_btn);                
            //取得標題的文本內容
            String title = channelList.get(position);
            vRss.channel.setText(title);            
            Log.e("guojs",channelList.get(row));
            //設置按鍵檢監聽器
            vRss.textLayout.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    String channelName=channelList.get(row);
                    Intent it=new Intent();
                    Log.e("channel-url",mChannel.getUrlByChannel(channelName));
                    //傳遞當前點擊RSS源對應的URL地址
                    it.putExtra("channel", mChannel.getUrlByChannel(channelName));
                    it.setClass(SelectChannel.this, ActivityMain.class);
                    //啓動顯示當前RSS源對應信息的界面
                    startActivity(it);
                }                
            });
            //刪除當前RSS源
            vRss.delBtn.setOnClickListener(new OnClickListener() {                
                public void onClick(View v) {
                    delRssInfo();                    
                }
                private void delRssInfo() {
                    //刪除成功
                    if(-1 != mChannel.DelChannelInfo(channelList.get(row)))
                    {
                        Toast.makeText(SelectChannel.this, "刪除成功!", Toast.LENGTH_SHORT).show();
                        //移除數組元素
                        channelList.remove(row);
                        //通知改變界面
                        mAdapter.notifyDataSetChanged();
                        //刪除失敗
                    }else{
                        Toast.makeText(SelectChannel.this, "刪除失敗!", Toast.LENGTH_SHORT).show();
                    }
                    
                }
            });
            return convertView;
        }        
    }
    //每一行元素的界面元素組成
    final class ViewHolder {
        public LinearLayout textLayout;
        public TextView channel;
        public Button delBtn;
    }
    
    //建立menu菜單
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //添加RSS源
        menu.add(0, MENU_ADD, 0, R.string.add_rss);
        //退出程序
        menu.add(0,MENU_QUIT,1,R.string.rss_quit);
        return super.onCreateOptionsMenu(menu);
    }        
    //爲menu菜單按鍵綁定監聽器
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        //添加RSS源
        case MENU_ADD:
            Intent intent = new Intent();
            intent.setClass(SelectChannel.this, AddRss.class);
            startActivity(intent);
            return true;
            //退出程序
        case MENU_QUIT:
            SelectChannel.this.finish();
        default:
            break;
        }
        return super.onOptionsItemSelected(item);
    }
}

5.添加頻道

界面

Screenshot_2013-11-18-17-18-41

Screenshot_2013-11-18-17-18-48

add_rss_dialog.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:id="@+id/show_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/title_show"
        />
    <!-- RSS源地址 -->
    <EditText
        android:layout_marginTop="3dp"
        android:id="@+id/rss_add"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text=""/>    
    <!-- 按鍵佈局 -->    
    <LinearLayout 
        android:layout_marginTop="30dp"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <!-- 驗證按鈕 -->
        <Button
            android:id="@+id/verify_rss"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text="@string/rss_verify"
            />
        <!-- 添加按鈕 -->
        <Button
            android:id="@+id/add_rss"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text="@string/rss_add"
            />
        <!-- 退出程序 -->
        <Button
            android:id="@+id/quit_rss"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text="@string/rss_quit"
            />
    </LinearLayout>
</LinearLayout>

ADDRss.java

package com.rss.activity;

import java.net.URL;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import com.rss.data.ChannelDataHelper;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.os.Handler;
import android.os.Message;

//RSS源添加界面
public class AddRss extends Activity {
    // 添加按鈕
    private Button addRss;
    // 檢驗按鈕
    private Button verifyRss;
    // 退出按鈕
    private Button quit;
    // RSS源地址
    private EditText rssText;
    // RSS源數據庫操做類
    ChannelDataHelper mChannelData;
    Context mContext;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 0x123:
                Toast.makeText(mContext, "驗證經過", Toast.LENGTH_SHORT).show();
                break;
            case 0x234:
                Toast.makeText(mContext, "驗證失敗", Toast.LENGTH_SHORT).show();
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_rss_dialog);
        mContext = this;
        // 實例化RSS源數據庫操做類
        mChannelData = new ChannelDataHelper(this);
        // 初始化界面元素
        addRss = (Button) findViewById(R.id.add_rss);
        verifyRss = (Button) findViewById(R.id.verify_rss);
        quit = (Button) findViewById(R.id.quit_rss);
        rssText = (EditText) findViewById(R.id.rss_add);
        // 設置按鍵監聽器
        addRss.setOnClickListener(clickListener);
        verifyRss.setOnClickListener(clickListener);
        quit.setOnClickListener(clickListener);
    }

    // 按鍵監聽器
    OnClickListener clickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            // 添加按鈕
            case R.id.add_rss:
                saveRss();
                break;
            // 檢驗地址
            case R.id.verify_rss:
                verifyRss(rssText.getText().toString());
                break;
            // 退出添加界面
            case R.id.quit_rss:
                Intent it = new Intent();
                it.setClass(AddRss.this, SelectChannel.class);
                // 進入RSS源選擇界面
                startActivity(it);
                AddRss.this.finish();
                break;
            default:
                break;
            }

        }
    };

    String rssAddress,rssName;
    // 保存RSS源
    protected void saveRss() {
        //rssAddress = rssText.getText().toString().trim();
        //rssName = "";//verifyRss(rssAddress);
        // RSS源地址正確並正確保存
        if (rssName != null && rssName != "默認"
                && (-1 != mChannelData.SaveChannelInfo(rssName, rssAddress))) {
            Toast.makeText(mContext, "保存成功!", Toast.LENGTH_SHORT).show();
            rssText.setText("");
        } else {
            Toast.makeText(mContext, "保存失敗!", Toast.LENGTH_SHORT).show();
        }
    }

    // 驗證RSS源地址的正確性,返回RSS源的標題
    private void verifyRss(final String urlString) {
        new Thread() {
            public void run() {
                try {
                    rssAddress = urlString;                    
                    URL url = new URL(urlString);
                    // 實例化SAX解析工廠類
                    SAXParserFactory factory = SAXParserFactory.newInstance();
                    // SAX解析器
                    SAXParser parser = factory.newSAXParser();
                    XMLReader xmlReader = parser.getXMLReader();
                    // SAX處理類
                    getRssChannel rssHandler = new getRssChannel();
                    xmlReader.setContentHandler(rssHandler);
                    // 取得url網址內容
                    InputSource is = new InputSource(url.openStream());
                    // 解析url網址內容
                    xmlReader.parse(is);
                    Log.e("channelName", rssHandler.getChannel());
                    rssName = rssHandler.getChannel();
                    if(rssName!="默認")
                    {
                        Message msg = new Message();
                        msg.what = 0x123;
                        msg.obj = "";
                        handler.sendMessage(msg);
                    }        
                    else
                    {
                        Message msg = new Message();
                        msg.what = 0x234;
                        msg.obj = "";
                        handler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    Log.e("channnelName", e.toString());
                }
            }
        }.start();
    }

    class getRssChannel extends DefaultHandler {
        // 標誌位,用於表示RSS源的位置
        int flag = 1;
        String channel = "默認";

        public getRssChannel() {
        }

        // 返回channel信息
        public String getChannel() {
            return channel;
        }

        // 文檔開始
        @Override
        public void startDocument() throws SAXException {
        }

        // 文檔結尾
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
        }

        // 開始解析標籤
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            if (localName.equals("channel")) {
                flag = 1;
                return;
            }
            // 一旦進入了item,則將標誌爲設置爲0
            if (localName.equals("item")) {
                flag = 0;
                return;
            }
            // 在item外面遇到title標籤將標誌位設置爲2
            if (flag == 1) {
                if (localName.equals("title")) {
                    flag = 2;
                }
            }
        }

        // 標籤結束
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
        }

        // 解析標籤內容
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            if (length <= 5)
                return;
            String theString = new String(ch, start, length);
            // 當標誌位爲2代表當前正在 解析RSS源標題的標籤
            if (flag == 2) {
                // 保存RSS源標題
                Log.e("channel", theString);
                channel = theString;
                flag = 0;
            }
        }
    }
}

6.RSS數據處理,SAX

RssHandler.java

package com.rss.sax;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.ext.DefaultHandler2;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

import com.rss.data.RssFeed;
import com.rss.data.RssItem;
//RSS數據SAX解析
public class RssHandler extends DefaultHandler {
    RssFeed rssFeed;
    RssItem rssItem;
    private static boolean a = false;
    String lastElementName = "";
    final int RSS_TITLE = 1;
    final int RSS_LINK = 2;
    final int RSS_DESCRIPTION = 3;
    final int RSS_PUBDATE = 5;
    int currentstate = 0;
    
    public RssHandler() {
        
    }
    //返回rssFeed形式的信息
    public RssFeed getFeed() {
        return rssFeed;
    }
    //開始解析文檔
    public void startDocument()throws SAXException {
        System.out.println("startDocument");
        //實例化RssFeed類和RssItem類
        rssFeed = new RssFeed();
        rssItem = new RssItem();
    }
    //文檔結束
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
    //開始解析標籤
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        //channel標籤
        if(localName.equals("channel")) {
            currentstate = 0;
            return;
        }
        //item標籤
        if(localName.equals("item")) {
            rssItem = new RssItem();
            return;
        }
        //title標籤
        if(localName.equals("title")) {
            currentstate = RSS_TITLE;
            return;
        }
        //詳細信息標籤
        if(localName.equals("description")) {    
                //跳過第一次遇到的description標籤
            if(a == true) {
                currentstate = RSS_DESCRIPTION;
                return;
            } else {
                a = true;
                return;
            }
        }
        //連接
        if(localName.equals("link")) {
            currentstate = RSS_LINK;
            return;
        }
        //日期
        if(localName.equals("pubDate")) {
            currentstate = RSS_PUBDATE;
            return;
        }
        currentstate = 0;
    }
    //標籤結束
    @Override
    public void endElement(String uri, String localName, String qName)    
            throws SAXException {
        //將信息添加到rssFeed中
        if(localName.equals("item")) {
            rssFeed.addItem(rssItem);
            return;
        }
    }
    //解析標籤間的文本
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if(length <= 5) return ;
        String theString = new String(ch, start, length);
        switch (currentstate) {
        //標題
        case RSS_TITLE:
            rssItem.setTitle(theString);
            Log.e("title",theString);
            currentstate = 0;
            break;
            //連接
        case RSS_LINK:
            rssItem.setLink(theString);
            currentstate = 0;
            break;
            //詳細信息
        case RSS_DESCRIPTION:
            System.out.println("RSS_DESCRIPTION=" + theString);        
            if(a == true) {
                rssItem.setDescription(theString);
                currentstate = 0;
            }else {            
                a = true;
            }
            break;
            //日期
        case RSS_PUBDATE:
            rssItem.setPubDate(theString);
            currentstate = 0;
            break;
        default:
            return;
        }
    }
}

7.查看

Screenshot_2013-11-18-17-18-57

Screenshot_2013-11-18-17-19-02

item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <!-- 文本區域 -->
    <LinearLayout
            android:id="@+id/textLayout"
            android:orientation="vertical"
            android:layout_width="270dp"
            android:layout_height="fill_parent">
            <!-- 標題  -->     
            <TextView android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#FFFFFFFF"
                android:textSize="15dp" />
            <!-- 日期 -->
            <TextView android:id="@+id/pubdate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#FFFFFFFF"
                android:textSize="10dp" />     
        </LinearLayout>     
        <!--刪除按鍵  --> 
        <Button android:id="@+id/del_btn"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:text="刪除"
            android:layout_gravity="right" />
        
</LinearLayout>

ActivityMain.java

package com.rss.activity;

import java.net.URL;

import java.util.List;
import java.util.Map;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.rss.data.RssFeed;
import com.rss.sax.RssHandler;

import android.os.Handler;
import android.os.Message;

//RSS文本解析
public class ActivityMain extends ListActivity {
    // RSS源地址
    public String RSS_URL = "";
    public final String TAG = "RssReader";
    // RSS信息類
    private RssFeed feed;
    //
    private List<Map<String, Object>> mList;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 0x123:
                feed = (RssFeed) msg.obj;
                // 將RSS信息顯示到列表中
                showListView();
                break;
            }
        }
    };

    // 初始化函數
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle b = getIntent().getExtras();
        // 取得RSS地址
        RSS_URL = b.getString("channel");
        Log.e("guojs-->get url", RSS_URL);
        // 取得對應RSS源地址的信息
        getFeed(RSS_URL);
    }

    // 取得對應RSS源地址的信息
    private void getFeed(final String urlString) {
        new Thread() {
            public void run() {
                try {
                    URL url = new URL(urlString);
                    // 採用SAX解析
                    SAXParserFactory factory = SAXParserFactory.newInstance();
                    SAXParser parser = factory.newSAXParser();
                    XMLReader xmlReader = parser.getXMLReader();
                    // SAX解析類
                    RssHandler rssHandler = new RssHandler();
                    xmlReader.setContentHandler(rssHandler);
                    // 取得網頁信息
                    InputSource is = new InputSource(url.openStream());
                    // 解析網頁內容
                    xmlReader.parse(is);
                    Message msg = new Message();
                    msg.what = 0x123;
                    msg.obj = rssHandler.getFeed();
                    handler.sendMessage(msg);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    // 顯示RSS信息到列表中
    @SuppressWarnings("unchecked")
    private void showListView() {
        if (feed == null) {
            setTitle("RSS閱讀器");
            return;
        }
        // 取得RSS信息數組
        mList = feed.getAllItemsForListView();
        MyAdapter adapter = new MyAdapter(this);
        // 設置適配器
        setListAdapter(adapter);
        setSelection(0);
    }

    // 新建數據適配器類
    class MyAdapter extends BaseAdapter {
        private LayoutInflater mInflator;

        // 構造函數
        public MyAdapter(Context context) {
            this.mInflator = LayoutInflater.from(context);
        }

        // 取得列表數量
        public int getCount() {
            System.out.println("mList.size()=" + mList.size());
            return mList.size();
        }

        public Object getItem(int position) {
            return null;
        }

        // 取得item的id
        public long getItemId(int position) {
            return 0;
        }

        // 取得每一行元素的視圖
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewRss vRss = null;
            final int row = position;
            // 實例化界面元素類
            vRss = new ViewRss();
            // 膨脹出界面元素的視圖
            convertView = mInflator.inflate(R.layout.item, null);
            // 初始化界面元素
            vRss.mLayout = (LinearLayout) convertView
                    .findViewById(R.id.textLayout);
            vRss.title = (TextView) convertView.findViewById(R.id.title);
            vRss.pubdate = (TextView) convertView.findViewById(R.id.pubdate);
            vRss.delBtn = (Button) convertView.findViewById(R.id.del_btn);
            // 設置刪除按鈕不可見
            vRss.delBtn.setVisibility(View.INVISIBLE);
            convertView.setTag(vRss);
            // 取得日期
            String pubDate = (String) mList.get(position).get("pubDate");
            // 取得標題
            String title = (String) mList.get(position).get("title");
            // 設置標題
            vRss.title.setText(title);
            // 設置日期
            vRss.pubdate.setText(pubDate);
            // 爲textLayout設置按鍵監聽器
            vRss.mLayout.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    Intent intent = new Intent(ActivityMain.this,
                            ActivityShowDescription.class);
                    Bundle b = new Bundle();
                    // 綁定數據
                    b.putString("title", feed.getItem(row).getTitle());
                    b.putString("description", feed.getItem(row)
                            .getDescription());
                    b.putString("link", feed.getItem(row).getLink());
                    b.putString("pubdate", feed.getItem(row).getPubDate());
                    intent.putExtra("com.rss.data.RssFeed", b);
                    // 啓動查看RSS詳細信息界面
                    startActivity(intent);
                }
            });
            return convertView;
        }
    }

    // RSS界面元素類,用於存放RSS界面元素
    public final class ViewRss {
        public LinearLayout mLayout;
        // 標題
        public TextView title;
        // 日期
        public TextView pubdate;
        // 刪除按鍵
        public Button delBtn;
    }
}

showDescriptionActivity.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"
    >
    <WebView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1.0" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:text="收藏"
            android:id="@+id/store"
            />
        <Button
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="50dp"
            android:text="返回"
            android:id="@+id/back"
            />
    </LinearLayout>
</LinearLayout>

ActivityShowDescription.java

package com.rss.activity;

import com.rss.db.RssProvider;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.Toast;
//RSS詳細信息顯示
public class ActivityShowDescription extends Activity {
    //標題
    private String title = null;
    //日期
    private String pubdate = null;
    //詳細信息
    private String description = null;
    //連接
    private String link = null;
    //初始化函數
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.showdescription);                
        String content = null;
        Intent intent = getIntent();
        //取得intent攜帶的信息
        if(intent != null) {
            Bundle bundle = intent.getBundleExtra("com.rss.data.RssFeed");        
            title = bundle.getString("title");
            pubdate = bundle.getString("pubdate");
            description = bundle.getString("description");
            if(description== null)
                description="";
            link = bundle.getString("link");
            content ="內容:<br />" + description.replace('\n', ' ')
            + "<br /><br />連接:\n<a href=\"" + link +"\">"+link+"</a>"
            + "<br /><br />日期: " + pubdate;
        }else {
            content = "error!";
        }
        //設置當前界面的標題
        ActivityShowDescription.this.setTitle(title);
        //初始化頁面元素
        WebView textView = (WebView)findViewById(R.id.content);
        //將content顯示到網頁中
        textView.loadDataWithBaseURL("",content, "text/html", "UTF-8","");          
        Button backButton = (Button)findViewById(R.id.back);
        Button storeButton = (Button)findViewById(R.id.store);
        //爲按鍵綁定監聽器
        storeButton.setOnClickListener(new OnClickListener() {            
            public void onClick(View v) {
                //保存RSS數據到數據庫中
                storeDataRss();            
                Toast.makeText(ActivityShowDescription.this, "收藏成功!", Toast.LENGTH_LONG).show();
            }
        });
        
        backButton.setOnClickListener(new OnClickListener() {
            //關閉當前頁面
            public void onClick(View v) {
                ActivityShowDescription.this.finish();            
            }
        });
    }
    //保存RSS數據到數據庫中
    protected void storeDataRss() {
        ContentResolver cr = getContentResolver();
        ContentValues values = new ContentValues();
        values.put(RssProvider.RSS_TITLE, title);
        values.put(RssProvider.RSS_DESCRIPTION, description);
        values.put(RssProvider.RSS_PUBDATE, pubdate);
        values.put(RssProvider.RSS_LINK, link);        
        cr.insert(RssProvider.RSS_URI, values);        
    }    
}

AndroidManifest.xml

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

    <uses-sdk android:minSdkVersion="10" />

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

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <activity
            android:name=".LoginActivity"
            android:label="@string/login" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ActivityMain"
            android:label="@string/app_name" >
        </activity>
        <activity android:name=".SelectChannel" >
        </activity>
        <activity android:name=".ActivityShowDescription" >
        </activity>
        <activity android:name=".AddRss" >
        </activity>

        <provider
            android:name="com.rss.db.RssProvider"
            android:authorities="com.rss.activity" />
    </application>

</manifest>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, ActivityMain!</string>
    <string name="app_name">RSS閱讀器</string>
    <string name="login">登入RSS閱讀器</string>
    <string name="logining">正在進入中....</string>
    <string name="login_in">進入RSS閱讀器</string>
    <string name="add_rss">添加RSS源</string>
    <string name="add_rss_address">添加XML源地址</string>
    <string name="rss_add">添加</string>
    <string name="rss_verify">檢驗</string>
    <string name="rss_quit">退出</string>
    <string name="rss_browser">瀏覽器</string>
    <string name="title_show">請輸入要添加的Rss源:</string>
</resources>
相關文章
相關標籤/搜索