下面是ArticlesAdapter类的实现,它实现在src/shy/luo/ArticlesAdapter.java文件中:
  1. package shy.luo.article;   
  2.    
  3. import java.util.LinkedList;   
  4.    
  5. import shy.luo.providers.articles.Articles;   
  6. import android.content.ContentResolver;   
  7. import android.content.ContentUris;   
  8. import android.content.ContentValues;   
  9. import android.content.Context;   
  10. import android.content.IContentProvider;   
  11. import android.database.Cursor;   
  12. import android.net.Uri;   
  13. import android.os.Bundle;   
  14. import android.os.RemoteException;   
  15. import android.util.Log;   
  16.    
  17.    
  18. public class ArticlesAdapter {   
  19.         private static final String LOG_TAG = "shy.luo.article.ArticlesAdapter";   
  20.    
  21.         private ContentResolver resolver = null;   
  22.    
  23.         public ArticlesAdapter(Context context) {   
  24.                 resolver = context.getContentResolver();   
  25.         }   
  26.    
  27.         public long insertArticle(Article article) {   
  28.                 ContentValues values = new ContentValues();   
  29.                 values.put(Articles.TITLE, article.getTitle());   
  30.                 values.put(Articles.ABSTRACT, article.getAbstract());   
  31.                 values.put(Articles.URL, article.getUrl());   
  32.    
  33.                 Uri uri = resolver.insert(Articles.CONTENT_URI, values);   
  34.                 String itemId = uri.getPathSegments().get(1);   
  35.    
  36.                 return Integer.valueOf(itemId).longValue();   
  37.         }   
  38.    
  39.         public boolean updateArticle(Article article) {   
  40.                 Uri uri = ContentUris.withAppendedId(Articles.CONTENT_URI, article.getId());   
  41.    
  42.                 ContentValues values = new ContentValues();   
  43.                 values.put(Articles.TITLE, article.getTitle());   
  44.                 values.put(Articles.ABSTRACT, article.getAbstract());   
  45.                 values.put(Articles.URL, article.getUrl());   
  46.    
  47.                 int count = resolver.update(uri, values, nullnull);   
  48.    
  49.                 return count > 0;   
  50.         }   
  51.    
  52.         public boolean removeArticle(int id) {   
  53.                 Uri uri = ContentUris.withAppendedId(Articles.CONTENT_URI, id);   
  54.    
  55.                 int count = resolver.delete(uri, nullnull);   
  56.    
  57.                 return count > 0;   
  58.         }   
  59.    
  60.         public LinkedList<Article> getAllArticles() {   
  61.                 LinkedList<Article> articles = new LinkedList<Article>();   
  62.    
  63.                 String[] projection = new String[] {   
  64.                         Articles.ID,   
  65.                         Articles.TITLE,   
  66.                         Articles.ABSTRACT,   
  67.                         Articles.URL   
  68.                 };   
  69.    
  70.                 Cursor cursor = resolver.query(Articles.CONTENT_URI, projection, nullnull, Articles.DEFAULT_SORT_ORDER);   
  71.                 if (cursor.moveToFirst()) {   
  72.                         do {   
  73.                                 int id = cursor.getInt(0);   
  74.                                 String title = cursor.getString(1);   
  75.                                 String abs = cursor.getString(2);   
  76.                                 String url = cursor.getString(3);   
  77.    
  78.                                 Article article = new Article(id, title, abs, url);   
  79.                                 articles.add(article);   
  80.                         } while(cursor.moveToNext());   
  81.                 }   
  82.    
  83.                 return articles;   
  84.         }   
  85.    
  86.         public int getArticleCount() {   
  87.                 int count = 0;   
  88.    
  89.                 try {   
  90.                         IContentProvider provider = resolver.acquireProvider(Articles.CONTENT_URI);   
  91.                         Bundle bundle = provider.call(Articles.METHOD_GET_ITEM_COUNT, nullnull);   
  92.                         count = bundle.getInt(Articles.KEY_ITEM_COUNT, 0);   
  93.                 } catch(RemoteException e) {   
  94.                         e.printStackTrace();   
  95.                 }   
  96.    
  97.                 return count;   
  98.         }   
  99.    
  100.         public Article getArticleById(int id) {   
  101.                 Uri uri = ContentUris.withAppendedId(Articles.CONTENT_URI, id);   
  102.    
  103.                 String[] projection = new String[] {   
  104.                                 Articles.ID,   
  105.                     Articles.TITLE,   
  106.                     Articles.ABSTRACT,   
  107.                     Articles.URL   
  108.                 };   
  109.    
  110.                 Cursor cursor = resolver.query(uri, projection, nullnull, Articles.DEFAULT_SORT_ORDER);   
  111.    
  112.                 Log.i(LOG_TAG, "cursor.moveToFirst");   
  113.    
  114.                 if (!cursor.moveToFirst()) {   
  115.                         return null;   
  116.                 }   
  117.    
  118.                 String title = cursor.getString(1);   
  119.                 String abs = cursor.getString(2);   
  120.                 String url = cursor.getString(3);   
  121.    
  122.                 return new Article(id, title, abs, url);   
  123.         }   
  124.    
  125.         public Article getArticleByPos(int pos) {   
  126.                 Uri uri = ContentUris.withAppendedId(Articles.CONTENT_POS_URI, pos);   
  127.    
  128.                 String[] projection = new String[] {   
  129.                                 Articles.ID,   
  130.                     Articles.TITLE,   
  131.                     Articles.ABSTRACT,   
  132.                     Articles.URL   
  133.                 };   
  134.    
  135.                 Cursor cursor = resolver.query(uri, projection, nullnull, Articles.DEFAULT_SORT_ORDER);   
  136.                 if (!cursor.moveToFirst()) {   
  137.                         return null;   
  138.                 }   
  139.    
  140.                 int id = cursor.getInt(0);   
  141.                 String title = cursor.getString(1);   
  142.                 String abs = cursor.getString(2);   
  143.                 String url = cursor.getString(3);   
  144.    
  145.                 return new Article(id, title, abs, url);   
  146.         }   
  147. }   
         这个类首先在构造函数里面获得应用程序上下文的ContentResolver接口,然后通过就可以通过这个接口来访问ArticlesProvider中的文章信息了。成员函数insertArticle、updateArticle和removeArticle分别用来新增、更新和删除一个文章信息条目;成员函数getAllArticlese用来获取所有的文章信息;成员函数getArticleById和getArticleByPos分别根据文章的ID和位置来获得具体文章信息条目;成员函数getArticleCount直接使用ContentProvider的未公开接口call来获得文章信息条目的数量,注意,这个函数要源代码环境下编译才能通过。
 
        下面是程序主界面MainActivity类的实现,它实现在src/shy/luo/article/MainActivity.java文件中:
  1. package shy.luo.article;   
  2.    
  3. import shy.luo.providers.articles.Articles;   
  4. import android.app.Activity;   
  5. import android.content.Context;   
  6. import android.content.Intent;   
  7. import android.database.ContentObserver;   
  8. import android.os.Bundle;   
  9. import android.os.Handler;   
  10. import android.util.Log;   
  11. import android.view.LayoutInflater;   
  12. import android.view.View;   
  13. import android.view.ViewGroup;   
  14. import android.widget.AdapterView;   
  15. import android.widget.BaseAdapter;   
  16. import android.widget.Button;   
  17. import android.widget.ListView;   
  18. import android.widget.TextView;   
  19.    
  20. public class MainActivity extends Activity implements View.OnClickListener, AdapterView.OnItemClickListener {   
  21.         private final static String LOG_TAG = "shy.luo.article.MainActivity";   
  22.    
  23.         private final static int ADD_ARTICAL_ACTIVITY = 1;   
  24.         private final static int EDIT_ARTICAL_ACTIVITY = 2;   
  25.    
  26.         private ArticlesAdapter aa = null;   
  27.         private ArticleAdapter adapter = null;   
  28.         private ArticleObserver observer = null;   
  29.    
  30.         private ListView articleList = null;   
  31.         private Button addButton = null;   
  32.    
  33.         @Override   
  34.         public void onCreate(Bundle savedInstanceState) {   
  35.                 super.onCreate(savedInstanceState);   
  36.                 setContentView(R.layout.main);   
  37.    
  38.                 aa = new ArticlesAdapter(this);   
  39.    
  40.                 articleList = (ListView)findViewById(R.id.listview_article);   
  41.                 adapter = new ArticleAdapter(this);   
  42.                 articleList.setAdapter(adapter);   
  43.                 articleList.setOnItemClickListener(this);   
  44.    
  45.                 observer = new ArticleObserver(new Handler());   
  46.                 getContentResolver().registerContentObserver(Articles.CONTENT_URI, true, observer);   
  47.    
  48.                 addButton = (Button)findViewById(R.id.button_add);   
  49.                 addButton.setOnClickListener(this);   
  50.    
  51.                 Log.i(LOG_TAG, "MainActivity Created");   
  52.         }   
  53.    
  54.         @Override   
  55.         public void onDestroy() {   
  56.                 super.onDestroy();   
  57.                 getContentResolver().unregisterContentObserver(observer);   
  58.         }   
  59.    
  60.         @Override   
  61.         public void onClick(View v) {   
  62.                 if(v.equals(addButton)) {   
  63.                         Intent intent = new Intent(this, ArticleActivity.class);   
  64.                         startActivityForResult(intent, ADD_ARTICAL_ACTIVITY);   
  65.                 }   
  66.         }   
  67.    
  68.         @Override   
  69.         public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {   
  70.                 Intent intent = new Intent(this, ArticleActivity.class);   
  71.    
  72.                 Article article = aa.getArticleByPos(pos);   
  73.                 intent.putExtra(Articles.ID, article.getId());   
  74.                 intent.putExtra(Articles.TITLE, article.getTitle());   
  75.                 intent.putExtra(Articles.ABSTRACT, article.getAbstract());   
  76.                 intent.putExtra(Articles.URL, article.getUrl());   
  77.    
  78.                 startActivityForResult(intent, EDIT_ARTICAL_ACTIVITY);   
  79.         }   
  80.    
  81.         @Override   
  82.         public void onActivityResult(int requestCode,int resultCode, Intent data) {   
  83.                 super.onActivityResult(requestCode, resultCode, data);   
  84.    
  85.                 switch(requestCode) {   
  86.                 case ADD_ARTICAL_ACTIVITY: {   
  87.                         if(resultCode == Activity.RESULT_OK) {   
  88.                                 String title = data.getStringExtra(Articles.TITLE);   
  89.                                 String abs = data.getStringExtra(Articles.ABSTRACT);   
  90.                                 String url = data.getStringExtra(Articles.URL);   
  91.    
  92.                                 Article article = new Article(-1, title, abs, url);   
  93.                                 aa.insertArticle(article);   
  94.                         }   
  95.    
  96.                         break;   
  97.                 }   
  98.    
  99.                 case EDIT_ARTICAL_ACTIVITY: {   
  100.                         if(resultCode == Activity.RESULT_OK) {   
  101.                                 int action = data.getIntExtra(ArticleActivity.EDIT_ARTICLE_ACTION, -1);   
  102.                                 if(action == ArticleActivity.MODIFY_ARTICLE) {   
  103.                                         int id = data.getIntExtra(Articles.ID, -1);   
  104.                                         String title = data.getStringExtra(Articles.TITLE);   
  105.                                         String abs = data.getStringExtra(Articles.ABSTRACT);   
  106.                                         String url = data.getStringExtra(Articles.URL);   
  107.    
  108.                                         Article article = new Article(id, title, abs, url);   
  109.                                         aa.updateArticle(article);   
  110.                                 } else if(action == ArticleActivity.DELETE_ARTICLE)     {   
  111.                                         int id = data.getIntExtra(Articles.ID, -1);   
  112.    
  113.                                         aa.removeArticle(id);   
  114.                                 }   
  115.    
  116.                         }   
  117.    
  118.                         break;   
  119.                 }   
  120.                 }   
  121.         }   
  122.    
  123.         private class ArticleObserver extends ContentObserver {   
  124.                 public ArticleObserver(Handler handler) {   
  125.                         super(handler);   
  126.                 }   
  127.    
  128.                 @Override   
  129.                 public void onChange (boolean selfChange) {   
  130.                         adapter.notifyDataSetChanged();   
  131.                 }   
  132.         }   
  133.    
  134.         private class ArticleAdapter extends BaseAdapter {   
  135.                 private LayoutInflater inflater;   
  136.    
  137.                 public ArticleAdapter(Context context){   
  138.                           inflater = LayoutInflater.from(context);   
  139.                 }   
  140.    
  141.                 @Override   
  142.                 public int getCount() {   
  143.                         return aa.getArticleCount();   
  144.                 }   
  145.    
  146.                 @Override   
  147.                 public Object getItem(int pos) {   
  148.                         return aa.getArticleByPos(pos);   
  149.                 }   
  150.    
  151.                 @Override   
  152.                 public long getItemId(int pos) {   
  153.                         return aa.getArticleByPos(pos).getId();   
  154.                 }   
  155.    
  156.                 @Override   
  157.                 public View getView(int position, View convertView, ViewGroup parent) {   
  158.                         Article article = (Article)getItem(position);   
  159.    
  160.                         if (convertView == null) {   
  161.                                 convertView = inflater.inflate(R.layout.item, null);   
  162.                         }   
  163.    
  164.                         TextView titleView = (TextView)convertView.findViewById(R.id.textview_article_title);   
  165.                         titleView.setText("Title: " + article.getTitle());   
  166.    
  167.                         TextView abstractView = (TextView)convertView.findViewById(R.id.textview_article_abstract);   
  168.                         abstractView.setText("Abstract: " + article.getAbstract());   
  169.    
  170.                         TextView urlView = (TextView)convertView.findViewById(R.id.textview_article_url);   
  171.                         urlView.setText("URL: " + article.getUrl());   
  172.    
  173.                         return convertView;   
  174.                 }   
  175.         }   
  176. }   
      在应用程序的主界面中,我们使用一个ListView来显示文章信息条目,这个ListView的数据源由ArticleAdapter类来提供,而ArticleAdapter类又是通过ArticlesAdapter类来获得ArticlesProvider中的文章信息的。在MainActivity的onCreate函数,我们还通过应用程序上下文的ContentResolver接口来注册了一个ArticleObserver对象来监控ArticlesProvider中的文章信息。一旦ArticlesProvider中的文章信息发生变化,就会通过ArticleAdapter类来实时更新ListView中的文章信息。
 
        下面是ArticleActivity类的实现,它实现在src/shy/luo/article/ArticleActivity.java文件中:
  1. package shy.luo.article;   
  2.    
  3. import shy.luo.providers.articles.Articles;   
  4. import android.app.Activity;   
  5. import android.content.Intent;   
  6. import android.os.Bundle;   
  7. import android.util.Log;   
  8. import android.view.View;   
  9. import android.widget.Button;   
  10. import android.widget.EditText;   
  11.    
  12. public class ArticleActivity extends Activity implements View.OnClickListener {   
  13.         private final static String LOG_TAG = "shy.luo.article.ArticleActivity";   
  14.    
  15.         public final static String EDIT_ARTICLE_ACTION = "EDIT_ARTICLE_ACTION";   
  16.         public final static int MODIFY_ARTICLE = 1;   
  17.         public final static int DELETE_ARTICLE = 2;   
  18.    
  19.         private int articleId = -1;   
  20.    
  21.         private EditText titleEdit = null;   
  22.         private EditText abstractEdit = null;   
  23.         private EditText urlEdit = null;   
  24.    
  25.         private Button addButton = null;   
  26.         private Button modifyButton = null;   
  27.         private Button deleteButton = null;   
  28.         private Button cancelButton = null;   
  29.    
  30.         @Override   
  31.         public void onCreate(Bundle savedInstanceState) {   
  32.                 super.onCreate(savedInstanceState);   
  33.                 setContentView(R.layout.article);   
  34.    
  35.                 titleEdit = (EditText)findViewById(R.id.edit_article_title);   
  36.                 abstractEdit = (EditText)findViewById(R.id.edit_article_abstract);   
  37.                 urlEdit = (EditText)findViewById(R.id.edit_article_url);   
  38.    
  39.                 addButton = (Button)findViewById(R.id.button_add_article);   
  40.                 addButton.setOnClickListener(this);   
  41.    
  42.                 modifyButton = (Button)findViewById(R.id.button_modify);   
  43.                 modifyButton.setOnClickListener(this);   
  44.    
  45.                 deleteButton = (Button)findViewById(R.id.button_delete);   
  46.                 deleteButton.setOnClickListener(this);   
  47.    
  48.                 cancelButton = (Button)findViewById(R.id.button_cancel);   
  49.                 cancelButton.setOnClickListener(this);   
  50.    
  51.                 Intent intent = getIntent();   
  52.                 articleId = intent.getIntExtra(Articles.ID, -1);   
  53.    
  54.                 if(articleId != -1) {   
  55.                         String title = intent.getStringExtra(Articles.TITLE);   
  56.                         titleEdit.setText(title);   
  57.    
  58.                         String abs = intent.getStringExtra(Articles.ABSTRACT);   
  59.                         abstractEdit.setText(abs);   
  60.    
  61.                         String url = intent.getStringExtra(Articles.URL);   
  62.                         urlEdit.setText(url);   
  63.    
  64.                         addButton.setVisibility(View.GONE);   
  65.                 } else {   
  66.    
  67.                         modifyButton.setVisibility(View.GONE);   
  68.                         deleteButton.setVisibility(View.GONE);   
  69.                 }   
  70.    
  71.                 Log.i(LOG_TAG, "ArticleActivity Created");   
  72.         }   
  73.    
  74.         @Override   
  75.         public void onClick(View v) {   
  76.                 if(v.equals(addButton)) {   
  77.                         String title = titleEdit.getText().toString();   
  78.                         String abs = abstractEdit.getText().toString();   
  79.                         String url = urlEdit.getText().toString();   
  80.    
  81.                         Intent result = new Intent();   
  82.                         result.putExtra(Articles.TITLE, title);   
  83.                         result.putExtra(Articles.ABSTRACT, abs);   
  84.                         result.putExtra(Articles.URL, url);   
  85.    
  86.                         setResult(Activity.RESULT_OK, result);   
  87.                         finish();   
  88.                 } else if(v.equals(modifyButton)){   
  89.                         String title = titleEdit.getText().toString();   
  90.                         String abs = abstractEdit.getText().toString();   
  91.                         String url = urlEdit.getText().toString();   
  92.    
  93.                         Intent result = new Intent();   
  94.                         result.putExtra(Articles.ID, articleId);   
  95.                         result.putExtra(Articles.TITLE, title);   
  96.                         result.putExtra(Articles.ABSTRACT, abs);   
  97.                         result.putExtra(Articles.URL, url);   
  98.                         result.putExtra(EDIT_ARTICLE_ACTION, MODIFY_ARTICLE);   
  99.    
  100.                         setResult(Activity.RESULT_OK, result);   
  101.                         finish();   
  102.                 } else if(v.equals(deleteButton)) {   
  103.                         Intent result = new Intent();   
  104.                         result.putExtra(Articles.ID, articleId);   
  105.                         result.putExtra(EDIT_ARTICLE_ACTION, DELETE_ARTICLE);   
  106.    
  107.                         setResult(Activity.RESULT_OK, result);   
  108.                         finish();   
  109.                 } else if(v.equals(cancelButton)) {   
  110.                         setResult(Activity.RESULT_CANCELED, null);   
  111.                         finish();   
  112.    
  113.                 }   
  114.         }   
  115. }   
         在ArticleActivity窗口中,我们可以执行新增、更新和删除文章信息的操作。如果启动ArticleActivity时,没有把文章ID传进来,就说明要执行操作是新增文章信息;如果启动ArticleActivity时,把文章ID和其它信自都传进来了,就说明要执行的操作是更新或者删除文章,根据用户在界面点击的是更新按钮还是删除按钮来确定。