- 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>
実行結果
0 件のコメント:
コメントを投稿