- Googleトレンドへのアクセスは、AsyncTaskLoaderを使用して非同期で通信する。
- Googleトレンドから取得したXMLのパースはXmlPullParserで解析する。
- 取得したワードはリストビュー(ListView)で表示する。
MainActivity
package net.kuttya.googletrendaccesssample; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.util.Xml; import android.widget.ArrayAdapter; import android.widget.ListView; import org.xmlpull.v1.XmlPullParser; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; public class MainActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<String> { private final String GOOGLETREND_URL = "http://www.google.co.jp/trends/hottrends/atom/hourly"; private final String ENCODING = "UTF-8"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Googleトレンドからワードを取得(非同期) getSupportLoaderManager().initLoader(0, null, this); } @Override public Loader<String> onCreateLoader(int id, Bundle args) { // GoogleトレンドにアクセスするAsyncTaskLoaderを返す return new HttpAccessingTaskLoader(this, GOOGLETREND_URL); } @Override public void onLoadFinished(Loader<String> loader, String data) { // Googleトレンドから取得したXMLから、CDATAの部分を抽出 String htmlData = getHtmlData(data); // CDATAからワードを抽出 List<String> words = getListData(htmlData); // リストビューのアダプタを作成、Googleトレンドのワードを設定 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, words); // リストビューにアダプタを設定 ListView view = (ListView)findViewById(R.id.listView); view.setAdapter(adapter); } @Override public void onLoaderReset(Loader<String> loader) { } /** * Googleトレンドから取得したXMLデータから、CDATAの部分を抽出する * @param data 解析するXMLデータ * @return CDATA内のHTMLデータ */ private String getHtmlData(String data) { String htmlData = ""; try { // Xmlパーサで解析 XmlPullParser xmlPullParser = Xml.newPullParser(); xmlPullParser.setInput(new ByteArrayInputStream(data.getBytes(ENCODING)), ENCODING); int eventType; String tagName; while((eventType = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) { if(eventType == XmlPullParser.START_TAG) { tagName = xmlPullParser.getName(); // contentタグの中身を抽出する if(tagName.equals("content")) { htmlData = xmlPullParser.nextText(); break; } } } } catch(Exception e) { e.printStackTrace(); } return htmlData; } /** * CDATA内のHTMLからワードを抽出する * @param htmlData 解析するHTMLデータ * @return 抽出したワードのリスト */ private List<String> getListData(String htmlData) { List<String> listData = new ArrayList<String>(); try { // HTMLでもXmlパーサで解析可能 XmlPullParser xmlPullParser = Xml.newPullParser(); xmlPullParser.setInput(new ByteArrayInputStream(htmlData.getBytes(ENCODING)), ENCODING); // content内の構造は下記 // <li><span><a>データ</a></span></li> int eventType; String tagName; String word; boolean inLi = false; boolean inSpan = false; while((eventType = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) { switch(eventType) { case XmlPullParser.START_TAG: tagName = xmlPullParser.getName(); if(tagName.equals("li")) { inLi = true; break; } if(inLi != true) { break; } // <Li>タグ内部のみ以下を実施 if(tagName.equals("span")) { inSpan = true; break; } if(inSpan != true) { break; } // <span>タグ内部のみ以下を実施 if(tagName.equals("a")) { // ワードを抽出 word = xmlPullParser.nextText(); listData.add(word); } break; case XmlPullParser.END_TAG: tagName = xmlPullParser.getName(); if(tagName.equals("li")) { inLi = false; } else if(tagName.equals("span")) { inSpan = false; } break; } } } catch(Exception e) { e.printStackTrace(); } return listData; } }
AsyncTaskLoader
package net.kuttya.googletrendaccesssample; import android.content.Context; import android.support.v4.content.AsyncTaskLoader; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; /** * Created by junichi on 2016/01/02. */ public class HttpAccessingTaskLoader extends AsyncTaskLoader<String> { private String mUrl; public HttpAccessingTaskLoader(Context context, String url) { super(context); mUrl = url; } @Override public String loadInBackground() { String result = ""; try { // URL URL url = new URL(mUrl); // 接続 URLConnection connection = url.openConnection(); // 結果を文字列で返す BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while((line = br.readLine()) != null) { sb.append(line); } result = sb.toString(); } catch(Exception e) { e.printStackTrace(); } return result; } @Override protected void onStartLoading() { forceLoad(); } }
レイアウト
リストビューだけ。
<?xml version="1.0" encoding="utf-8"?> <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" tools:context="net.kuttya.googletrendaccesssample.MainActivity"> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listView" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true"/> </RelativeLayout>
AndroidManifest.xml
パーミッションの追加を忘れずに。
<?xml version="1.0" encoding="utf-8"?> <manifest package="net.kuttya.googletrendaccesssample" xmlns:android="http://schemas.android.com/apk/res/android"> <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"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest>