zoukankan      html  css  js  c++  java
  • Android ContentProvider的实现

      当Android中的应用需要访问其他应用的数据时,用ContentProvider可以很好的解决这个问题。今天介绍一下ContentProvider的用法。

      首先开发ContentProvider有两个步骤:

      1、开发一个ContentProvider的子类,该子类需要实现增、删、改、查等方法。

      2、在AndroidManifest.xml文件中注册该ContentProvider。

      下面通过一个实例来介绍一下ContentProvider到底怎么实现的。首先,我们也像系统一样把ContentProvider的Uri、数据列等信息以常量的形式公开出来、方便访问。为此,定义一个工具类,该类中只是包含一个public static的常量,该工具类的代码如下:

     1 public final class Words
     2 {
     3     // 定义该ContentProvider的Authority
     4     public static final String AUTHORITY 
     5         = "org.crazyit.providers.dictprovider";
     6     //定义一个静态内部类
     7     public static final class Word implements BaseColumns
     8     {
     9         // 定义Content所允许操作的3个数据列
    10         public final static String _ID = "_id";
    11         public final static String WORD = "word";
    12         public final static String DETAIL = "detail";
    13         // 定义该Content提供服务的两个Uri
    14         public final static Uri DICT_CONTENT_URI = 
    15             Uri.parse("content://" +  AUTHORITY + "/words");
    16         public final static Uri WORD_CONTENT_URI = 
    17             Uri.parse("content://" +  AUTHORITY + "/word");        
    18     }
    19 }

      上面的工具类只是定义了一些简单的常量的工具类,这个工具类的作用就是告诉其他应用访问该ContentProvider的一些常用的入口。
      接下来开发一个ContentProvider的子类,并重写其中的增、删、改、查等方法,代码如下:

      1 public class DictProvider extends ContentProvider
      2 {
      3     private static UriMatcher matcher
      4         = new UriMatcher(UriMatcher.NO_MATCH);
      5     private static final int WORDS = 1;
      6     private static final int WORD = 2;
      7     private MyDatabaseHelper dbOpenHelper;
      8     static
      9     {
     10         // 为UriMatcher注册两个Uri
     11         matcher.addURI(Words.AUTHORITY, "words", WORDS);
     12         matcher.addURI(Words.AUTHORITY, "word/#", WORD);
     13     }
     14     // 第一次调用该DictProvider时,系统先创建DictProvider对象,并回调该方法
     15     @Override
     16     public boolean onCreate()
     17     {
     18         dbOpenHelper = new MyDatabaseHelper(this.getContext(), "myDict.db3", 1);
     19         return true;
     20     }
     21     // 插入数据方法
     22     @Override
     23     public Uri insert(Uri uri, ContentValues values)
     24     {
     25         // 获得数据库实例
     26         SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
     27         // 插入数据,返回行ID
     28         long rowId = db.insert("dict", Words.Word._ID, values);
     29         // 如果插入成功返回uri
     30         if (rowId > 0)
     31         {
     32             // 在已有的 Uri的后面追加ID数据
     33             Uri wordUri = ContentUris.withAppendedId(uri, rowId);
     34             // 通知数据已经改变
     35             getContext().getContentResolver().notifyChange(wordUri, null);
     36             return wordUri;
     37         }
     38         return null;
     39     }
     40     // 删除数据的方法
     41     @Override
     42     public int delete(Uri uri, String selection, String[] selectionArgs)
     43     {
     44         SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
     45         // 记录所删除的记录数
     46         int num = 0;
     47         // 对于uri进行匹配。
     48         switch (matcher.match(uri))
     49         {
     50             case WORDS:
     51                 num = db.delete("dict", selection, selectionArgs);
     52                 break;
     53             case WORD:
     54                 // 解析出所需要删除的记录ID
     55                 long id = ContentUris.parseId(uri);
     56                 String where = Words.Word._ID + "=" + id;
     57                 // 如果原来的where子句存在,拼接where子句
     58                 if (selection != null && !selection.equals(""))
     59                 {
     60                     where = where + " and " + selection;
     61                 }
     62                 num = db.delete("dict", where, selectionArgs);
     63                 break;
     64             default:
     65                 throw new IllegalArgumentException("未知Uri:" + uri);
     66         }
     67         // 通知数据已经改变
     68         getContext().getContentResolver().notifyChange(uri, null);
     69         return num;
     70     }
     71     // 修改数据的方法
     72     @Override
     73     public int update(Uri uri, ContentValues values, String selection,
     74         String[] selectionArgs)
     75     {
     76         SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
     77         // 记录所修改的记录数
     78         int num = 0;
     79         switch (matcher.match(uri))
     80         {
     81             case WORDS:
     82                 num = db.update("dict", values, selection, selectionArgs);
     83                 break;
     84             case WORD:
     85                 // 解析出想修改的记录ID
     86                 long id = ContentUris.parseId(uri);
     87                 String where = Words.Word._ID + "=" + id;
     88                 // 如果原来的where子句存在,拼接where子句
     89                 if (selection != null && !selection.equals(""))
     90                 {
     91                     where = where + " and " + selection;
     92                 }
     93                 num = db.update("dict", values, where, selectionArgs);
     94                 break;
     95             default:
     96                 throw new IllegalArgumentException("未知Uri:" + uri);
     97         }
     98         // 通知数据已经改变
     99         getContext().getContentResolver().notifyChange(uri, null);
    100         return num;
    101     }
    102     // 查询数据的方法
    103     @Override
    104     public Cursor query(Uri uri, String[] projection, String selection,
    105         String[] selectionArgs, String sortOrder)
    106     {
    107         SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
    108         switch (matcher.match(uri))
    109         {
    110             case WORDS:
    111                 // 执行查询
    112                 return db.query("dict", projection, selection, selectionArgs,
    113                     null, null, sortOrder);
    114             case WORD:
    115                 // 解析出想查询的记录ID
    116                 long id = ContentUris.parseId(uri);
    117                 String where = Words.Word._ID + "=" + id;
    118                 // 如果原来的where子句存在,拼接where子句
    119                 if (selection != null && !"".equals(selection))
    120                 {
    121                     where = where + " and " + selection;
    122                 }
    123                 return db.query("dict", projection, where, selectionArgs, null,
    124                     null, sortOrder);
    125             default:
    126                 throw new IllegalArgumentException("未知Uri:" + uri);
    127         }
    128     }
    129     // 返回指定uri参数对应的数据的MIME类型
    130     @Override
    131     public String getType(Uri uri)
    132     {
    133         switch (matcher.match(uri))
    134         {
    135             // 如果操作的数据是多项记录
    136             case WORDS:
    137                 return "vnd.android.cursor.dir/org.crazyit.dict";
    138                 // 如果操作的数据是单项记录
    139             case WORD:
    140                 return "vnd.android.cursor.item/org.crazyit.dict";
    141             default:
    142                 throw new IllegalArgumentException("未知Uri:" + uri);
    143         }
    144     }
    145 }

    上面的DictProvider类继承了ContentProvider,并实现了操作数据的增、删、改、查等方法。接下来需要在AndroidManitest.xml文件中注册该ContentProvider,代码:

    1 <!-- 注册一个ContentProvider -->
    2         <provider android:name=".DictProvider" 
    3             android:authorities="org.crazyit.providers.dictprovider"/>

      至此,整个ContentProvider开发完成,为了测试它,我们需要新建一个工程。
      在新的工程里,我们需要把上面创建的工具类拷贝到新工程里,下面的是使用ContentProvider的代码:

     1 public class DictResolver extends Activity
     2 {
     3     ContentResolver contentResolver;
     4     Button insert = null;
     5     Button search = null;
     6     @Override
     7     public void onCreate(Bundle savedInstanceState)
     8     {
     9         super.onCreate(savedInstanceState);
    10         setContentView(R.layout.main);
    11         // 获取系统的ContentResolver对象
    12         contentResolver = getContentResolver();
    13         insert = (Button)findViewById(R.id.insert);
    14         search = (Button)findViewById(R.id.search);    
    15         // 为insert按钮的单击事件绑定事件监听器
    16         insert.setOnClickListener(new OnClickListener()
    17         {
    18             @Override
    19             public void onClick(View source)
    20             {
    21                 //获取用户输入
    22                 String word = ((EditText)findViewById(R.id.word))
    23                     .getText().toString();
    24                 String detail = ((EditText)findViewById(R.id.detail))
    25                     .getText().toString();
    26                 //插入生词记录
    27                 ContentValues values = new ContentValues();
    28                 values.put(Words.Word.WORD , word);
    29                 values.put(Words.Word.DETAIL , detail);
    30                 contentResolver.insert(Words.Word.DICT_CONTENT_URI , values);
    31                 //显示提示信息
    32                 Toast.makeText(DictResolver.this, "添加生词成功!" , 8000)
    33                     .show();
    34             }            
    35         });
    36         // 为search按钮的单击事件绑定事件监听器
    37         search.setOnClickListener(new OnClickListener()
    38         {
    39             @Override
    40             public void onClick(View source)
    41             {
    42                 // 获取用户输入
    43                 String key = ((EditText) findViewById(R.id.key)).getText()
    44                     .toString();
    45                 // 执行查询
    46                 Cursor cursor = contentResolver.query(
    47                     Words.Word.DICT_CONTENT_URI, null 
    48                     , "word like ? or detail like ?"
    49                     , new String[]{"%" + key + "%" , "%" + key + "%"} 
    50                     , null);
    51                 //创建一个Bundle对象
    52                 Bundle data = new Bundle();
    53                 data.putSerializable("data", converCursorToList(cursor));
    54                 //创建一个Intent
    55                 Intent intent = new Intent(DictResolver.this
    56                     , ResultActivity.class);
    57                 intent.putExtras(data);
    58                 //启动Activity
    59                 startActivity(intent);
    60             }
    61         });
    62     }
    63 
    64     private ArrayList<Map<String, String>> converCursorToList(
    65         Cursor cursor)
    66     {
    67         ArrayList<Map<String, String>> result 
    68             = new ArrayList<Map<String, String>>();
    69         // 遍历Cursor结果集
    70         while (cursor.moveToNext())
    71         {
    72             // 将结果集中的数据存入ArrayList中
    73             Map<String, String> map = new HashMap<String, String>();
    74             // 取出查询记录中第2列、第3列的值
    75             map.put(Words.Word.WORD, cursor.getString(1));
    76             map.put(Words.Word.DETAIL, cursor.getString(2));
    77             result.add(map);
    78         }
    79         return result;
    80     }
    81 }

    至此,测试ContentProvider的关键代码已经给出了,希望能够帮助大家,在此也希望大家多多关注本人。

  • 相关阅读:
    第一节课课堂总结--付胤
    自我介绍--付胤
    JavaScript面向对象的理解
    与redmine对接
    CCS3属性之text-overflow:ellipsis;的用法和注意之处
    自定义TextView带有各类.ttf字体的TextView
    百度地图sdk的使用
    DrawRightEditText自定义EditText实现有内容时右侧图标按钮显示无内容时右侧图标按钮隐藏加上为空时晃动动画(二)
    DrawRightEditText自定义EditText实现有内容时右侧图标按钮显示无内容时右侧图标按钮隐藏加上为空时晃动动画
    首页底部菜单FragmentTabHost的使用
  • 原文地址:https://www.cnblogs.com/phj981805903/p/3266514.html
Copyright © 2011-2022 走看看