[[Software/Android/アプリケーション開発テキスト]]

*Chapter 5 : サービスの作成 [#i24953d7]

 この章では簡易RSSリーダーを開発し、HTTP通信を使用するアプリケーションについて解説します。

 このアプリケーションは設定したRSSを取得して、一覧と詳細表示を行います。詳細画面には外部リンクを併せて表示し、タップすることで外部ブラウザが開くようにします。

 新規Androidアプリケーションプロジェクトを以下の設定で作成します。

-Project Nameに「RSSReader」と入力します
-Application Nameに「RSSReader」と入力します
-Package Nameに「com.beatcraft.rssreader」と入力します
-Create Activityにチェックを入れ、「RSSReaderActivity」と入力します 
~
~

**5-1. サービスクラスの作成 [#a61c3b95]
**5-2. ブロードキャストレシーバの作成 [#d0e9ec46]
**5-3. サービスを利用する [#f59de66b]

 ああああ

**5-4. サービス版RSSReader全ソースコード/AIDLファイル/XMLファイル [#n50fca06]

-リスト5-19 RSSReaderApplication.java : 
 package com.beatcraft.rssreader;
 
 import android.app.Application;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 
 public class RSSReaderApplication extends Application {
     private static final String CONF_NAME = "rssreader.conf";
 
     public static final int DEFAULT_NUM_OF_GET = 3;
     public static final int NUM_OF_FEED = 10;
 
     private int mNumOfGet = DEFAULT_NUM_OF_GET;
     private String mFeedURL[];
 
 
     @Override
     public void onCreate() {
         mFeedURL = new String[NUM_OF_FEED];
         loadConfig();
     }
 
     public int numberOfGet() {
         return mNumOfGet;
     }
     public void setNumberOfGet(int numOfGet) {
         mNumOfGet = numOfGet;
     }
 
     public String feedURL(int index) {
         if ((index < 0) || (10 <= index)) {
             return null;
         }
         return mFeedURL[index];
     }
     public void setFeedURL(int index, String url) {
         if ((index < 0) || (NUM_OF_FEED <= index)) {
             return;
         }
         mFeedURL[index] = url;
     }
     public void clearFeedURL() {
         for (int i = 0; i < NUM_OF_FEED; ++i) {
             mFeedURL[i] = "";
         }
     }
 
     public void loadConfig() {
         SharedPreferences pref = getSharedPreferences(CONF_NAME, MODE_PRIVATE);
         mNumOfGet = pref.getInt("NumOfGet", DEFAULT_NUM_OF_GET);
         for (int i = 0; i < NUM_OF_FEED; ++i) {
             String key = String.format("FeedURL%02d", (i + 1));
             mFeedURL[i] = pref.getString(key, "");
         }
     }
 
     public void saveConfig() {
         SharedPreferences pref = getSharedPreferences(CONF_NAME, MODE_PRIVATE);
         Editor pe = pref.edit();
 
         pe.putInt("NumOfGet", mNumOfGet);
         for (int i = 0; i < NUM_OF_FEED; ++i) {
             String key = String.format("FeedURL%02d", (i + 1));
             pe.putString(key, mFeedURL[i]);
         }
         pe.commit();
     }
 }
~

-リスト5-20 RSSReaderActivity.java : 
 package com.beatcraft.rssreader;
 
 import java.util.ArrayList;
 
 import android.app.ListActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
 import android.view.Window;
 import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.Toast;
 
 public class RSSReaderActivity extends ListActivity implements View.OnClickListener, ITaskEntity {
     private FeedList mList = null;
 
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setContentView(R.layout.main);
 
         Button button;
         button = (Button) findViewById(R.id.Get);
         button.setOnClickListener(this);
         button = (Button) findViewById(R.id.Config);
         button.setOnClickListener(this);
 
         getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
                 FeedItem item = (FeedItem) getListView().getItemAtPosition(pos);
                 Intent intent = new Intent(getApplicationContext(), com.beatcraft.rssreader.DescActivity.class);
                 intent.putExtra("FeedTitle", item.feedTitle());
                 intent.putExtra("ArticleTitle", item.articleTitle());
                 intent.putExtra("PubDate", item.pubDate());
                 intent.putExtra("Description", item.description());
                 intent.putExtra("Link", item.link());
                 startActivity(intent);
             }
         });
     }
 
 
     @Override
     public void onClick(View view) {
         int id = view.getId();
 
         switch (id) {
         case R.id.Get:
             mList = null;
             HttpAccessTask task = new HttpAccessTask(this);
             task.execute(this);
             break;
 
         case R.id.Config:
             showConfig();
             break;
         }
     }
 
 
     @Override
     public void backgroundProc() {
         RSSReaderApplication app = (RSSReaderApplication) getApplication();
         mList = new FeedList();
         mList.get(app);
     }
 
 
     @Override
     public void postProc() {
         if (mList.count() > 0) {
             ArrayList<FeedItem> list = mList.getList();
             if (list != null) {
                 FeedAdapter adapter = new FeedAdapter(this, list);
                 setListAdapter(adapter);
             }
         }
         else {
             Toast.makeText(this, "* NOT FOUND *", Toast.LENGTH_SHORT).show();
         }
     }
 
     private void showConfig() {
         Intent intent = new Intent(getApplicationContext(), com.beatcraft.rssreader.ConfigActivity.class);
         startActivity(intent);
     }
 }
~

-リスト5-21 DescActivity.java : 
 package com.beatcraft.rssreader;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
 import android.view.Window;
 import android.webkit.WebView;
 import android.widget.Button;
 import android.widget.TextView;
 
 public class DescActivity extends Activity implements View.OnClickListener {
     private static final String WEBVIEW_BEGIN =
         "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head><body bgcolor=\"#f6f6f6\">";
     private static final String WEBVIEW_LINK = "<p><a href=\"%s\">%s</a></p>";
     private static final String WEBVIEW_END = "</body></html>";
 
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setContentView(R.layout.description);
 
         Button button = (Button) findViewById(R.id.Back);
         button.setOnClickListener(this);
 
         Intent intent = getIntent();
         if (intent != null) {
             String tmp = "";
             String desc = "";
             TextView tv;
 
             tv = (TextView) findViewById(R.id.FeedTitle);
             tmp = intent.getStringExtra("FeedTitle");
             tv.setText(tmp);
             tv = (TextView) findViewById(R.id.ArticleTitle);
             tmp = intent.getStringExtra("ArticleTitle");
             tv.setText(tmp);
             tv = (TextView) findViewById(R.id.PubDate);
             tmp = intent.getStringExtra("PubDate");
             tv.setText(tmp);
 
             WebView wv = (WebView) findViewById(R.id.Description);
             desc = WEBVIEW_BEGIN;
             tmp = intent.getStringExtra("Link");
             desc += String.format(WEBVIEW_LINK, tmp, tmp);
             tmp = intent.getStringExtra("Description");
             desc += tmp + WEBVIEW_END;
             wv.loadDataWithBaseURL("about:blank", desc, "text/html", "utf-8", null);
         }
     }
 
     @Override
     public void onClick(View view) {
         if (view.getId() == R.id.Back) {
             finish();
         }
     }
 }
~

-リスト5-22 ConfigActivity.java : 
 package com.beatcraft.rssreader;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
 import android.view.Window;
 import android.view.WindowManager.LayoutParams;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.Spinner;
 
 public class ConfigActivity extends Activity implements View.OnClickListener {
     public static final int REQUEST_RECOMMEND = 1234;
     private static final int NUM_OF_GET_LIST[] = {1, 3, 5};
 
     private Spinner mNumOfGet;
     private EditText mFeedURL[];
 
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         this.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
         setContentView(R.layout.config);
 
         RSSReaderApplication app = (RSSReaderApplication) getApplication();
 
         ArrayAdapter<CharSequence> adapter;
         adapter = ArrayAdapter.createFromResource(this, R.array.number_of_get, android.R.layout.simple_spinner_item);
         adapter.setDropDownViewResource(
             android.R.layout.simple_spinner_dropdown_item);
         mNumOfGet = (Spinner) findViewById(R.id.NumOfGet);
         mNumOfGet.setAdapter(adapter);
         for (int i = 0; i < 3; ++i) {
             if (NUM_OF_GET_LIST[i] == app.numberOfGet()) {
                 mNumOfGet.setSelection(i);
                 break;
             }
         }
 
         mFeedURL = new EditText[RSSReaderApplication.NUM_OF_FEED];
         mFeedURL[0] = (EditText) findViewById(R.id.FeedURL01);
         mFeedURL[1] = (EditText) findViewById(R.id.FeedURL02);
         mFeedURL[2] = (EditText) findViewById(R.id.FeedURL03);
         mFeedURL[3] = (EditText) findViewById(R.id.FeedURL04);
         mFeedURL[4] = (EditText) findViewById(R.id.FeedURL05);
         mFeedURL[5] = (EditText) findViewById(R.id.FeedURL06);
         mFeedURL[6] = (EditText) findViewById(R.id.FeedURL07);
         mFeedURL[7] = (EditText) findViewById(R.id.FeedURL08);
         mFeedURL[8] = (EditText) findViewById(R.id.FeedURL09);
         mFeedURL[9] = (EditText) findViewById(R.id.FeedURL10);
         for (int i = 0; i < RSSReaderApplication.NUM_OF_FEED; ++i) {
             mFeedURL[i].setText(app.feedURL(i));
         }
 
         Button button;
         button = (Button) findViewById(R.id.Recommend);
         button.setOnClickListener(this);
         button = (Button) findViewById(R.id.Cancel);
         button.setOnClickListener(this);
         button = (Button) findViewById(R.id.Regist);
         button.setOnClickListener(this);
     }
 
     @Override
     public void onClick(View view) {
         int id = view.getId();
 
         switch (id) {
         case R.id.Recommend:
             showRecommend();
             break;
 
         case R.id.Cancel:
             finish();
             break;
 
         case R.id.Regist:
             regist();
             break;
         }
     }
 
     protected void onActivityResult(int reqCode, int result, Intent data) {
         super.onActivityResult(reqCode, result, data);
 
         if (result == RESULT_OK) {
             if (reqCode == REQUEST_RECOMMEND) {
                 int count = 0;
                 count = data.getIntExtra("RecommendCount", 0);
                 for (int i = 0; i < count; ++i) {
                     String key = "";
                     String url = "";
                     key = String.format("Recommend%02d", (i + 1));
                     url = data.getStringExtra(key);
                     if (url.equals("") == false) {
                         for (int j = 0; j < RSSReaderApplication.NUM_OF_FEED; ++j) {
                             String tmp = mFeedURL[j].getText().toString().trim();
                             if (tmp.equals("") == true) {
                                 mFeedURL[j].setText(url);
                                 break;
                             }
                         }
                     }
                 }
             }
         }
     }
 
     private void showRecommend() {
         Intent intent = new Intent(getApplicationContext(), com.beatcraft.rssreader.RecommendActivity.class);
         startActivityForResult(intent, REQUEST_RECOMMEND);
     }
 
     private void regist() {
         RSSReaderApplication app = (RSSReaderApplication) getApplication();
         app.setNumberOfGet(NUM_OF_GET_LIST[mNumOfGet.getSelectedItemPosition()]);
         app.clearFeedURL();
         for (int i = 0, j = 0; i < RSSReaderApplication.NUM_OF_FEED; ++i) {
             String url = mFeedURL[i].getText().toString().trim();
             if (url.equals("") == false) {
                 app.setFeedURL(j++, url);
             }
         }
         app.saveConfig();
         finish();
     }
 }
~

-リスト5-23 RecommendActivity.java : 
 package com.beatcraft.rssreader;
 
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.NameValuePair;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.Credentials;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 import org.xmlpull.v1.XmlPullParser;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Xml;
 import android.view.View;
 import android.view.Window;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.Spinner;
 
 public class RecommendActivity extends Activity implements View.OnClickListener, ITaskEntity {
     private static final String GENRE[] = {"news", "music", "movie"};
     private static final String POST_DOMAIN = "labs.beatcraft.com";
     private static final String POST_PATH = "/ja/androidtext/recommend.php";
     private static final String POST_USER = "beatandroid";
     private static final String POST_PASS = "sample";
     private static final int NUM_OF_RECOMMEND = 3;
 
     private Spinner mGenre;
     private CheckBox mFeedCheck[];
     private String mRecommendTitle[];
     private String mRecommendURL[];
     private Button mAddFeed;
     private int mStat = -1;
 
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setContentView(R.layout.recommend);
 
         ArrayAdapter<CharSequence> adapter;
         adapter = ArrayAdapter.createFromResource(this, R.array.genre, android.R.layout.simple_spinner_item);
         adapter.setDropDownViewResource(
             android.R.layout.simple_spinner_dropdown_item);
         mGenre = (Spinner) findViewById(R.id.Genre);
         mGenre.setAdapter(adapter);
 
         Button button;
         button = (Button) findViewById(R.id.Search);
         button.setOnClickListener(this);
         button = (Button) findViewById(R.id.Back);
         button.setOnClickListener(this);
         mAddFeed = (Button) findViewById(R.id.AddFeed);
         mAddFeed.setOnClickListener(this);
 
         mFeedCheck = new CheckBox[NUM_OF_RECOMMEND];
         mFeedCheck[0] = (CheckBox) findViewById(R.id.Feed01);
         mFeedCheck[1] = (CheckBox) findViewById(R.id.Feed02);
         mFeedCheck[2] = (CheckBox) findViewById(R.id.Feed03);
         mRecommendTitle = new String[NUM_OF_RECOMMEND];
         mRecommendURL = new String[NUM_OF_RECOMMEND];
     }
 
     @Override
     public void onClick(View view) {
         int id = view.getId();
 
         switch (id) {
         case R.id.Search:
             HttpAccessTask task = new HttpAccessTask(this);
             task.execute(this);        
             break;
 
         case R.id.Back:
             finish();
             break;
 
         case R.id.AddFeed:
             addFeed();
             break;
         }
     }
 
     @Override
     public void backgroundProc() {
         for (int i = 0; i < NUM_OF_RECOMMEND; ++i) {
             mRecommendTitle[i] = "";
             mRecommendURL[i] = "";
         }
         mStat = get(GENRE[mGenre.getSelectedItemPosition()]);
     }
 
     @Override
     public void postProc() {
         if (mStat == 0) {
             for (int i = 0; i < NUM_OF_RECOMMEND; ++i) {
                 mFeedCheck[i].setText(mRecommendTitle[i]);
                 mFeedCheck[i].setVisibility(View.VISIBLE);
                 mFeedCheck[i].setChecked(false);
             }
             mAddFeed.setVisibility(View.VISIBLE);
         }
         else {
             for (int i = 0; i < NUM_OF_RECOMMEND; ++i) {
                 mFeedCheck[i].setText("");
                 mFeedCheck[i].setVisibility(View.INVISIBLE);
                 mFeedCheck[i].setChecked(false);
             }
             mAddFeed.setVisibility(View.INVISIBLE);
         }
     }
 
     private int get(String genre) {
         String url = "http://" + POST_DOMAIN + POST_PATH;
 
         DefaultHttpClient client = new DefaultHttpClient();
         if (client != null) {
             client.getParams().setParameter("http.socket.timeout", new Integer(15000));
             HttpPost method = null;
             try {
                 method = new HttpPost(url);
             }
             catch (Exception e) {
                 e.printStackTrace();
             }
             if (method == null) {
                 return -1;
             }
             HttpResponse response = null;
             try {
                 List<NameValuePair> pair = new ArrayList<NameValuePair>();
                 pair.add(new BasicNameValuePair("genre", genre));
                 method.setEntity(new UrlEncodedFormEntity(pair, HTTP.UTF_8));
 
                 Credentials cred = new UsernamePasswordCredentials(POST_USER, POST_PASS);
                 client.getCredentialsProvider().setCredentials(new AuthScope(POST_DOMAIN, 80), cred);
 
                 response = client.execute(method);
                 int ret = response.getStatusLine().getStatusCode();
                 if (ret == HttpStatus.SC_OK) {
                     InputStream is = response.getEntity().getContent();
                     return parse(is);
                 }
             }
             catch (Exception e) {
                 e.printStackTrace();
             }
             finally {
                 client.getConnectionManager().shutdown();
             }
         }
         return -1;
     }
 
     private int parse(InputStream is) {
         int count = 0;
         boolean inFeed = false;
 
         XmlPullParser p = Xml.newPullParser();
         try {
             p.setInput(is, null);
             int event = p.getEventType();
             while (event != XmlPullParser.END_DOCUMENT) {
                 String elem = null;
                 String tmp = null;
 
                 switch (event) {
                 case XmlPullParser.START_TAG:
                     elem = p.getName();
                     if (elem.equals("feed") == true) {
                         if (inFeed == true) {
                             count++;
                             if (count >= NUM_OF_RECOMMEND) {
                                 return 0;
                             }
                         }
                         inFeed = true;
                     }
                     else if (elem.equals("title") == true) {
                         tmp = p.nextText();
                         if (tmp != null) {
                             mRecommendTitle[count] = tmp;
                         }
                     }
                     else if (elem.equals("url") == true) {
                         tmp = p.nextText();
                         if (tmp != null) {
                             mRecommendURL[count] = tmp;
                         }
                     }
                     break;
 
                 case XmlPullParser.END_TAG:
                     elem = p.getName();
                     if (elem.equals("feed") == true) {
                         count++;
                         if (count >= NUM_OF_RECOMMEND) {
                             return 0;
                         }
                         inFeed = false;
                     }
                     break;
                 }
 
                 event = p.next();
             }
         }
         catch (Exception e) {
             e.printStackTrace();
             return -1;
         }
         return 0;
     }
 
     private void addFeed() {
         int count = 0;
         Intent result = new Intent();
 
         for (int i = 0; i < NUM_OF_RECOMMEND; ++i) {
             if (mFeedCheck[i].isChecked() == true) {
                 String key = "";
                 key = String.format("Recommend%02d", (count + 1));
                 result.putExtra(key, mRecommendURL[i]);
                 count++;
             }
         }
         result.putExtra("RecommendCount", count);
         setResult(RESULT_OK, result);
         finish();
     }
 
 }
~

-リスト5-24 FeedItem.java : 
 package com.beatcraft.rssreader;
 
 public class FeedItem {
     public static final int ITEMTYPE_FEEDCHANNEL = 0;
     public static final int ITEMTYPE_FEEDITEM = 1;
 
     private int mItemType;
     private String mFeedTitle = "";
     private String mArticleTitle = "";
     private String mPubDate = "";
     private String mDescription = "";
     private String mLink = "";
 
     public FeedItem(int itemType) {
         mItemType = itemType;
     }
 
     public int itemType() {
         return mItemType;
     }
 
     public String feedTitle() {
         return mFeedTitle;
     }
     public void setFeedTitle(String title) {
         mFeedTitle = title;
     }
 
     public String articleTitle() {
         return mArticleTitle;
     }
     public void setArticleTitle(String title) {
         mArticleTitle = title;
     }
 
     public String pubDate() {
         return mPubDate;
     }
     public void setPubDate(String pubDate) {
         mPubDate = pubDate;
     }
 
     public String description() {
         return mDescription;
     }
     public void setDescription(String description) {
         mDescription = description;
     }
 
     public String link() {
         return mLink;
     }
     public void setLink(String link) {
         mLink = link;
     }
 }
~

-リスト5-25 FeedList.java : 
 package com.beatcraft.rssreader;
 
 import java.io.InputStream;
 import java.util.ArrayList;
 
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.xmlpull.v1.XmlPullParser;
 
 import android.util.Xml;
 
 public class FeedList {
     private ArrayList<FeedItem> mList = null;
     
     public FeedList() {
         mList = new ArrayList<FeedItem>();
     }
 
     public ArrayList<FeedItem> getList() {
         return mList;
     }
     public int count() {
         if (mList != null) {
             return mList.size();
         }
         return 0;
     }
 
     public int get(RSSReaderApplication app) {
         int success = 0;
         for (int i = 0; i < RSSReaderApplication.NUM_OF_FEED; ++i) {
             String url = app.feedURL(i);
             if (url.equals("") == true) {
                 continue;
             }
 
             DefaultHttpClient client = new DefaultHttpClient();
             if (client != null) {
                 client.getParams().setParameter("http.socket.timeout", new Integer(15000));
                 HttpGet method = null;
                 try {
                     method = new HttpGet(url);
                 }
                 catch (Exception e) {
                     e.printStackTrace();
                 }
                 if (method == null) {
                     continue;
                 }
                 HttpResponse response = null;
                 try {
                     response = client.execute(method);
                     int ret = response.getStatusLine().getStatusCode();
                     if (ret == HttpStatus.SC_OK) {
                         InputStream is = response.getEntity().getContent();
                         if (parse(is, app.numberOfGet()) > 0) {
                             success++;
                         }
                         is.close();
                     }
                 }
                 catch (Exception e) {
                     e.printStackTrace();
                 }
                 finally {
                     client.getConnectionManager().shutdown();
                 }
             }
         }
         return success;
     }
 
     private int parse(InputStream is, int max) {
         int count = 0;
         boolean inChannel = false;
         boolean inItem = false;
         FeedItem item = null;
         String feedTitle = "";
 
         XmlPullParser p = Xml.newPullParser();
         try {
             p.setInput(is, null);
             int event = p.getEventType();
             while (event != XmlPullParser.END_DOCUMENT) {
                 String elem = null;
                 String tmp = null;
 
                 switch (event) {
                 case XmlPullParser.START_TAG:
                     elem = p.getName();
                     if (elem.equals("channel") == true) {
                         inChannel = true;
                         item = new FeedItem(FeedItem.ITEMTYPE_FEEDCHANNEL);
                     }
                     else if (elem.equals("item") == true) {
                         if (inChannel == true) {
                             if (item != null) {
                                 mList.add(item);
                                 item = null;
                                 count++;
                             }
                             inChannel = false;
                         }
                         inItem = true;
                         item = new FeedItem(FeedItem.ITEMTYPE_FEEDITEM);
                         item.setFeedTitle(feedTitle);
                     }
                     else if (elem.equals("title") == true) {
                         tmp = p.nextText();
                         if ((tmp != null) && (item != null)) {
                             if (inChannel == true) {
                                 feedTitle = tmp;
                                 item.setFeedTitle(tmp);
                             }
                             else if (inItem == true) {
                                 item.setArticleTitle(tmp);
                             }
                         }
                     }
                     else if ((elem.equals("pubDate") == true) 
                             || (elem.equals("date") == true)) {
                         if (inItem == true) {
                             tmp = p.nextText();
                             if ((tmp != null) && (item != null)) {
                                 item.setPubDate(tmp);
                             }
                         }
                     }
                     else if (elem.equals("description") == true) {
                         if (inItem == true) {
                             tmp = p.nextText();
                             if ((tmp != null) && (item != null)) {
                                 item.setDescription(tmp);
                             }
                         }
                     }
                     else if (elem.equals("link") == true) {
                         if (inItem == true) {
                             tmp = p.nextText();
                             if ((tmp != null) && (item != null)) {
                                 item.setLink(tmp);
                             }
                         }
                     }
                     break;
                     
                 case XmlPullParser.END_TAG:
                     elem = p.getName();
                     if (elem.equals("channel") == true) {
                         if (inChannel == true) {
                             if (item != null) {
                                 mList.add(item);
                                 item = null;
                                 count++;
                             }
                             inChannel = false;
                         }
                     }
                     else if (elem.equals("item") == true) {
                         if (inItem == true) {
                             if (item != null) {
                                 mList.add(item);
                                 item = null;
                                 count++;
                                 max--;
                                 if (max == 0) {
                                     return count;
                                 }
                             }
                             inItem = false;
                         }
                     }
                 }
 
                 event = p.next();
             }
         }
         catch (Exception e) {
             e.printStackTrace();
             return 0;
         }
         return count;
     }
 }
~

-リスト5-26 FeedAdapter.java : 
 package com.beatcraft.rssreader;
 
 import java.util.List;
 
 import android.content.Context;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.TextView;
 
 public class FeedAdapter extends ArrayAdapter<FeedItem> {
     private LayoutInflater mInflate;
 
     public FeedAdapter(Context context, List<FeedItem> obj) {
         super(context, 0, obj);
         mInflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     }
 
     @Override
     public boolean isEnabled(int pos) {
         FeedItem item = getItem(pos);
         if (item.itemType() == FeedItem.ITEMTYPE_FEEDCHANNEL) {
             return false;
         }
         return true;
     }
 
     public View getView(final int pos, View convView, ViewGroup parent) {
         View view = convView;
         FeedItem item = getItem(pos);
 
         switch (item.itemType()) {
         case FeedItem.ITEMTYPE_FEEDCHANNEL:
             view = buildChannel(item);
             break;
 
         case FeedItem.ITEMTYPE_FEEDITEM:
             view = buildItem(item);
             break;
         }
         return view;
     }
 
     private View buildChannel(FeedItem item) {
         View view = null;
         view = mInflate.inflate(R.layout.item_channel, null);
 
         TextView tv;
         tv = (TextView) view.findViewById(R.id.FeedTitle);
         tv.setText(item.feedTitle());
 
         return view;
     }
 
     private View buildItem(FeedItem item) {
         View view = null;
         view = mInflate.inflate(R.layout.item_item, null);
 
         TextView tv;
         tv = (TextView) view.findViewById(R.id.ArticleTitle);
         tv.setText(item.articleTitle());
         tv = (TextView) view.findViewById(R.id.PubDate);
         tv.setText(item.pubDate());
 
         return view;
     }
 }
~

-リスト5-27 ITaskEntity.java : 
 package com.beatcraft.rssreader;
 
 public interface ITaskEntity {
     void backgroundProc();
     void postProc();
 }
~

-リスト5-28 HttpAccessTask.java : 
 package com.beatcraft.rssreader;
 
 import android.app.Activity;
 import android.app.ProgressDialog;
 import android.os.AsyncTask;
 
 public class HttpAccessTask extends AsyncTask<ITaskEntity, Integer, Void> {
     private Activity mActivity;
     private ProgressDialog mDialog;
     private ITaskEntity mITaskEntity;
 
     public HttpAccessTask(Activity activity) {
         mActivity = activity;
     }
 
     @Override
     protected void onPreExecute() {
         mDialog = new ProgressDialog(mActivity);
         mDialog.setMessage(mActivity.getString(R.string.loading));
         mDialog.show();
     }
 
     @Override
     protected Void doInBackground(ITaskEntity... params) {
         mITaskEntity = params[0];
         mITaskEntity.backgroundProc();
         return null;
     }
 
     @Override
     protected void onPostExecute(Void v) {
         mITaskEntity.postProc();
         mDialog.dismiss();
         mDialog = null;
     }
 }
~

-リスト5-34 main.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" >
 
     <LinearLayout
         android:id="@+id/linearLayout1"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_margin="10dip" >
 
         <Button
             android:id="@+id/Get"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginLeft="5dip"
             android:layout_marginRight="5dip"
             android:layout_weight="1"
             android:text="@string/get_feed" />
 
         <Button
             android:id="@+id/Config"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginLeft="5dip"
             android:layout_marginRight="5dip"
             android:layout_weight="1"
             android:text="@string/config" />
     </LinearLayout>
 
     <ListView
         android:id="@+id/android:list"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:fastScrollEnabled="true" >
     </ListView>
 
 </LinearLayout>
~

-リスト5-35 item_channel.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:background="#cccccc"
     android:orientation="vertical" >
 
     <TextView
         android:id="@+id/FeedTitle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_margin="5dip"
         android:text="FeedTitle"
         android:textColor="#000000"
         android:textSize="16dip"
         android:textStyle="bold" />
 
 </LinearLayout>
~

-リスト5-36 item_item.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:id="@+id/ArticleTitle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_margin="5dip"
         android:text="ArticleTitle" />
 
     <TextView
         android:id="@+id/PubDate"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="right"
         android:layout_margin="5dip"
         android:text="pubDate" />
 
 </LinearLayout>
~

-リスト5-37 description.xml : 
 <?xml version="1.0" encoding="utf-8"?>
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/ScrollView"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent" >
 
     <LinearLayout
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:orientation="vertical" >
 
         <Button
             android:id="@+id/Back"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_margin="5dip"
             android:text="@string/back" />
 
         <TextView
             android:id="@+id/FeedTitle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:text="FeedTitle"
             android:textSize="16dip"
             android:textStyle="bold" />
 
         <TextView
             android:id="@+id/ArticleTitle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:text="ArticleTitle" />
 
         <TextView
             android:id="@+id/PubDate"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="right"
             android:layout_marginRight="10dip"
             android:text="pubDate" />
 
         <android.webkit.WebView
             android:id="@+id/Description"
             android:layout_width="fill_parent"
             android:layout_height="0dip"
             android:layout_margin="5dip"
             android:layout_weight="1" >
         </android.webkit.WebView>
     </LinearLayout>
 
 </ScrollView>
~

-リスト5-38 config.xml : 
 <?xml version="1.0" encoding="utf-8"?>
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/ScrollView"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent" >
 
     <LinearLayout
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:orientation="vertical" >
 
         <LinearLayout
             android:id="@+id/linearLayout1"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_margin="10dip" >
 
             <TextView
                 android:id="@+id/LabelNumOfGet"
                 android:layout_width="wrap_content"
                 android:layout_height="fill_parent"
                 android:gravity="center_vertical"
                 android:text="@string/label_number_of_get" />
 
             <Spinner
                 android:id="@+id/NumOfGet"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content" />
 
             <Button
                 android:id="@+id/Recommend"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginLeft="10dip"
                 android:layout_weight="1"
                 android:text="@string/recommend" />
         </LinearLayout>
 
         <EditText
             android:id="@+id/FeedURL01"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" >
 
             <requestFocus />
         </EditText>
 
         <EditText
             android:id="@+id/FeedURL02"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <EditText
             android:id="@+id/FeedURL03"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <EditText
             android:id="@+id/FeedURL04"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <EditText
             android:id="@+id/FeedURL05"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <EditText
             android:id="@+id/FeedURL06"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <EditText
             android:id="@+id/FeedURL07"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <EditText
             android:id="@+id/FeedURL08"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <EditText
             android:id="@+id/FeedURL09"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <EditText
             android:id="@+id/FeedURL10"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_marginRight="10dip"
             android:inputType="textUri" />
 
         <LinearLayout
             android:id="@+id/linearLayout2"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_margin="10dip" >
 
             <Button
                 android:id="@+id/Cancel"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginLeft="5dip"
                 android:layout_marginRight="5dip"
                 android:layout_weight="1"
                 android:text="@string/cancel" />
 
             <Button
                 android:id="@+id/Regist"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginLeft="5dip"
                 android:layout_marginRight="5dip"
                 android:layout_weight="1"
                 android:text="@string/regist" />
         </LinearLayout>
     </LinearLayout>
 
 </ScrollView>
~

-リスト5-39 recommend.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" >
 
     <LinearLayout
         android:id="@+id/linearLayout1"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_margin="10dip" >
 
         <TextView
             android:id="@+id/LabelGenre"
             android:layout_width="wrap_content"
             android:layout_height="fill_parent"
             android:gravity="center_vertical"
             android:text="@string/label_genre" />
 
         <Spinner
             android:id="@+id/Genre"
             android:layout_width="120dip"
             android:layout_height="wrap_content" />
 
         <Button
             android:id="@+id/Search"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginLeft="10dip"
             android:layout_weight="1"
             android:text="@string/search" />
     </LinearLayout>
 
     <Button
         android:id="@+id/Back"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_margin="5dip"
         android:text="@string/back" />
 
     <CheckBox
         android:id="@+id/Feed01"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_margin="5dip"
         android:text="CheckBox"
         android:visibility="invisible" />
 
     <CheckBox
         android:id="@+id/Feed02"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_margin="5dip"
         android:text="CheckBox"
         android:visibility="invisible" />
 
     <CheckBox
         android:id="@+id/Feed03"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_margin="5dip"
         android:text="CheckBox"
         android:visibility="invisible" />
 
     <Button
         android:id="@+id/AddFeed"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_horizontal"
         android:layout_margin="5dip"
         android:text="@string/addfeed"
         android:visibility="invisible" />
 
 </LinearLayout>
~

-リスト5-40 AndroidManifest.xml : 
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.beatcraft.rssreader"
     android:versionCode="1"
     android:versionName="1.0" >
 
     <uses-sdk android:minSdkVersion="7" />
 
     <application
         android:icon="@drawable/ic_launcher"
         android:label="@string/app_name"
         android:name="com.beatcraft.rssreader.RSSReaderApplication" >
         <activity
             android:label="@string/app_name"
             android:name=".RSSReaderActivity" >
             <intent-filter >
                 <action android:name="android.intent.action.MAIN" />
 
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
         <activity
             android:label="@string/app_name"
             android:name=".ConfigActivity" />
         <activity
             android:label="@string/app_name"
             android:name=".DescActivity" />
         <activity
             android:label="@string/app_name"
             android:name=".RecommendActivity" />
     </application>
 
     <uses-permission android:name="android.permission.INTERNET" >
     </uses-permission>
 
 </manifest>
~

----
RIGHT:内藤

BC::labsへの質問は、bc9-dev @ googlegroups.com までお願い致します。
トップ   新規 一覧 単語検索 最終更新   最終更新のRSS