androidでRSSを取得して一覧表示
参考
XMLをパース(解析)する | Tech Booster
これを見て必要な分を加工して取得する
画面
MainActivity用
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listView" android:layout_centerHorizontal="true" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" /> </RelativeLayout>
リストビューの明細用
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="50dp" android:weightSum="1"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Large Text" android:id="@+id/textView" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="Medium Text" android:id="@+id/textView2" android:layout_weight="0.08" /> </LinearLayout>
内部処理
MainActivity
package jp.mshige1979.app.sampleapp01; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.os.Handler; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private Handler handler; private final String RSS_URL = "http://m-shige1979.hatenablog.com/rss"; private String RssText; private ListView listview; List<Item> list = new ArrayList<Item>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler = new Handler(); setContentView(R.layout.activity_main); // 紐付け listview = (ListView)findViewById(R.id.listView); // ArrayAdapterへ設定 RowItemAdapter rowAdapater = new RowItemAdapter(this, 0, list); // リストビューへ設定 listview.setAdapter(rowAdapater); // リストをクリック listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // リストビューの項目を取得 ListView listview = (ListView) parent; Item item = (Item) listview.getItemAtPosition(position); // インテントのインスタンス生成 Intent intent = new Intent(MainActivity.this, MainActivity2Activity.class); // 値をセットする intent.putExtra("title", item.getTitle()); intent.putExtra("link", item.getLink()); // 次画面のアクティビティ起動 startActivity(intent); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // メニューボタンを追加 MenuItem item1 = menu.add("UPDATE"); item1.setIcon(android.R.drawable.ic_menu_upload); item1.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { Thread thread1 = new Thread() { @Override public void run() { try { // URLよりRSSを取得 RssText = RssParse.getRss(MainActivity.this, RSS_URL); list = RssParse.parse(RssText); // handler handler.post(new Runnable() { @Override public void run() { // 読み込み終了 RowItemAdapter rowAdapater = new RowItemAdapter(MainActivity.this, 0, list); listview.setAdapter(rowAdapater); Toast.makeText(MainActivity.this, "読み込み終了", Toast.LENGTH_SHORT).show(); } }); } catch (Exception e) { Log.d("sample", e.getMessage()); } } }; thread1.start(); return false; } }); // 画面にメニューを表示 item1.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
その他
Itemクラス
package jp.mshige1979.app.sampleapp01; public class Item { private String title; private String pubDate; private String link; public String getTitle() { return title; } public String getLink() { return link; } public String getPubDate() { return pubDate; } public void setTitle(String title) { this.title = title; } public void setLink(String link) { this.link = link; } public void setPubDate(String pubDate) { this.pubDate = pubDate; } }
パース、取得クラス
package jp.mshige1979.app.sampleapp01; import android.content.Context; import android.net.http.AndroidHttpClient; import android.util.Log; import android.util.Xml; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; /** * RSSを取得するクラス */ public class RssParse{ public static String getRss(Context context, String url) throws IOException{ StringBuilder sb = new StringBuilder(); AndroidHttpClient client = AndroidHttpClient.newInstance("TEST"); HttpGet get = new HttpGet(url); try{ // リクエストを取得 HttpResponse response = client.execute(get); BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); String line = null; while((line = br.readLine()) != null){ sb.append(line); } }finally { // 閉じる client.close(); } return sb.toString(); } public static List<Item> parse(String xml){ List<Item> list = new ArrayList<Item>(); // XMLパーサを生成 XmlPullParser xmlPullParser = Xml.newPullParser(); // 入力データを設定 try { xmlPullParser.setInput(new StringReader(xml)); } catch (XmlPullParserException e) { Log.d("sample", "Error"); } // 解析して記事のタイトルやリンク、日時を取得 try { int eventType; String data = null; int itemFlg = -1; String fieldName = null; Item item = new Item(); eventType = xmlPullParser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if(eventType == XmlPullParser.START_DOCUMENT) { Log.d("sample", "Start document"); } else if(eventType == XmlPullParser.END_DOCUMENT) { Log.d("sample", "End document"); } else if(eventType == XmlPullParser.START_TAG) { data = xmlPullParser.getName(); Log.d("sample", "Start tag "+ data); if(data.equals("item")){ itemFlg = 1; item = new Item(); } fieldName = data; } else if(eventType == XmlPullParser.END_TAG) { data = xmlPullParser.getName(); Log.d("sample", "End tag "+ data); if(data.equals("item")){ itemFlg = 0; list.add(item); } } else if(eventType == XmlPullParser.TEXT) { data = xmlPullParser.getText(); Log.d("sample", "Text "+ data); if(itemFlg == 1){ if(fieldName.equals("title")){ Log.d("sample", "title = "+ data); item.setTitle(data); fieldName = ""; } if(fieldName.equals("pubDate")){ Log.d("sample", "pubDate = "+ data); item.setPubDate(data); fieldName = ""; } if(fieldName.equals("link")){ Log.d("sample", "link = "+ data); item.setLink(data); fieldName = ""; } } } eventType = xmlPullParser.next(); } } catch (Exception e) { Log.d("sample", "Error"); } return list; } }
リストビュー用アダプター
package jp.mshige1979.app.sampleapp01; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; import java.util.List; public class RowItemAdapter extends ArrayAdapter<Item> { private LayoutInflater layoutinflater; // コンストラクタ public RowItemAdapter(Context context, int textViewResourceId, List<Item> objects){ super(context, textViewResourceId, objects); layoutinflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(int position, View convertView, ViewGroup parent) { // 指定行のデータを取得 Item detail = (Item)getItem(position); // nullの場合のみ再作成 if(null == convertView){ convertView = layoutinflater.inflate(R.layout.row, null); } // 行のデータを項目へ設定 TextView text1 = (TextView)convertView.findViewById(R.id.textView); text1.setText(detail.getTitle()); TextView text2 = (TextView)convertView.findViewById(R.id.textView2); text2.setText(detail.getLink()); // 返却 return convertView; } }
このへんは今までのパクリを流用
結果
詳細画面を用意して、ページを表示するようにする
もう少し
画面
MainActivity2Activity
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context="jp.mshige1979.app.sampleapp01.MainActivity2Activity"> <WebView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/webView" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout>
内部処理
MainActivity2Activity
package jp.mshige1979.app.sampleapp01; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.webkit.WebView; import android.widget.Toast; public class MainActivity2Activity extends Activity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_activity2); // webview webView = (WebView)findViewById(R.id.webView); // インテントを取得 Intent intent = getIntent(); // インテントに保存されたデータを取得 String data = intent.getStringExtra("title"); String link = intent.getStringExtra("link"); setTitle(data); // URLを読み込み webView.loadUrl(link); // data Toast.makeText(MainActivity2Activity.this,data, Toast.LENGTH_SHORT).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.menu_main_activity2, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
結果
所感
なんとなく非同期処理のやり方などが慣れてきたかもしれない…