博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android ContentProvider的实现
阅读量:5311 次
发布时间:2019-06-14

本文共 9782 字,大约阅读时间需要 32 分钟。

  当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提供服务的两个Uri14         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     @Override104     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                 // 解析出想查询的记录ID116                 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     @Override131     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 
2

  至此,整个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             @Override19             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             @Override40             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                 //创建一个Intent55                 Intent intent = new Intent(DictResolver.this56                     , ResultActivity.class);57                 intent.putExtras(data);58                 //启动Activity59                 startActivity(intent);60             }61         });62     }63 64     private ArrayList
> converCursorToList(65 Cursor cursor)66 {67 ArrayList
> result 68 = new ArrayList
>();69 // 遍历Cursor结果集70 while (cursor.moveToNext())71 {72 // 将结果集中的数据存入ArrayList中73 Map
map = new HashMap
();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的关键代码已经给出了,希望能够帮助大家,在此也希望大家多多关注本人。

转载于:https://www.cnblogs.com/phj981805903/p/3266514.html

你可能感兴趣的文章
自己动手写ORM(01):解析表达式树生成Sql碎片
查看>>
如何使用USBWebserver在本机快速建立网站测试环境
查看>>
变量提升
查看>>
[Flex] flex手机项目如何限制横竖屏?只允许横屏?
查看>>
tensorflow的graph和session
查看>>
JavaScript动画打开半透明提示层
查看>>
jquery-jqzoom 插件 用例
查看>>
1007. Maximum Subsequence Sum (25)
查看>>
查看oracle数据库的连接数以及用户
查看>>
【数据结构】栈结构操作示例
查看>>
三.野指针和free
查看>>
activemq5.14+zookeeper3.4.9实现高可用
查看>>
TCP/IP详解学习笔记(3)IP协议ARP协议和RARP协议
查看>>
简单【用户输入验证】
查看>>
python tkinter GUI绘制,以及点击更新显示图片
查看>>
20130330java基础学习笔记-语句_for循环嵌套练习2
查看>>
Spring面试题
查看>>
C语言栈的实现
查看>>
代码为什么需要重构
查看>>
TC SRM 593 DIV1 250
查看>>