Android学习---通过内容提供者(ContentProvider)操作另外一个应用私有数据库的内容...
一.什么是ContentProvider?
ContentProvider直译过来就是内容提供者,主要作用就是A应用提供接口给B应用调用数据,和之前介绍的sharedPreference和直接开放文件访问类似,都是共享应用程序数据,不同的是之前的两种文件格式可能完全不同,如可能为xml,txt,sql等等,这里ContentProvider返回的数据格式是统一的,因此应用的更为广泛一点.
二.实例
这里使用的是A应用通过ContentProvider共享数据给B应用.这里A应用用的是前文中的android_db里的person表.B应用是新建的android_content_provider程序.
1.新创建android_content_provider应用程序
2.访问android_db共享的数据
创建好了应用程序以后,
/android_content_provider/src/com/example/android_content_provider/ContentProvider.java
package com.example.android_content_provider;import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log;public class ContentProvider extends Activity {private static String tag = "ContentProvider.class";/*** Called when the activity is first created.*/@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);//内容解析者ContentResolver contentResolver = getContentResolver();Uri uri = Uri.parse("content://com.amos.android_db.provider.PersonProvider/persons");Cursor cursor = contentResolver.query(uri, null, null, null, null);while(cursor.moveToNext()){String name = cursor.getString(cursor.getColumnIndex("name"));int age = cursor.getInt(cursor.getColumnIndex("age"));System.out.println("name:"+name+" age:"+age);Log.d(tag,"用户名:"+name+" 年龄:"+age);}} }
3.android_db开放共享数据接口
1)开放一个uri
/android_db/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.amos.android_db"android:versionCode="1"android:versionName="1.0"><instrumentation android:name="android.test.InstrumentationTestRunner"android:targetPackage="com.amos.android_db"></instrumentation><uses-sdk android:minSdkVersion="7"/><application android:label="@string/app_name"><uses-library android:name="android.test.runner"/><activity android:name="MyActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity> <!--给内容提供者提供定义一个uri,一般建议使用包名+类名,以供其它程序调用 --><provider android:authorities="com.amos.android_db.provider.PersonProvider" android:name=".provider.PersonProvider"> </provider></application> </manifest>
2).定义路径匹配(继承ContentProvider类)
/android_db/src/com/amos/android_db/provider/PersonProvider.java
package com.amos.android_db.provider;import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.util.Log; import com.amos.android_db.MyDBHelper; import com.amos.android_db.dao.Person; import com.amos.android_db.dao.PersonDao;import java.util.List;/*** Created by amosli on 14-6-17.*/ public class PersonProvider extends ContentProvider {//创建一个路径识别器//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码,也就是说如果找不到匹配的类型,返回-1private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);private static final int ALL_PERSON = 1;private static final int PERSON = 2;private static final int OTHER = 3;private static String tag="PersonProvider.class";static{//1.指定一个路径的匹配规则//如果路径满足content://com.amos.android_db.provider.PersonProvider/persons,返回值就是(ALL_PERSON)=1uriMatcher.addURI("com.amos.android_db.provider.PersonProvider","persons",ALL_PERSON);//2.如果路径满足content://com.amos.android_db.provider.PersonProvider/person/3,返回值就是(PERSON)=2//#号为通配符uriMatcher.addURI("com.amos.android_db.provider.PersonProvider","person/#",PERSON);//3.如果路径满足content://com.amos.android_db.provider.PersonProvider/other,返回值就是(OTHER)=3uriMatcher.addURI("com.amos.android_db.provider.PersonProvider","other",OTHER);}/*** 一般是对象第一次被创建时调用的方法** @return*/@Overridepublic boolean onCreate() {return false;}/*** 让别人去调用返回结果** @param uri* @param projection 选择的列* @param selection 查询条件* @param selectionArgs 查询条件的value* @param sortOrder 排序* @return*/@Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {int result = uriMatcher.match(uri);switch(result){//如果路径满足content://com.amos.android_db.provider.PersonProvider/persons,返回值就是(ALL_PERSON)=1case ALL_PERSON:PersonDao dao = new PersonDao(this.getContext());return dao.findAllByCursor();//2.如果路径满足content://com.amos.android_db.provider.PersonProvider/person/3,返回值就是(PERSON)=2case PERSON:long id = ContentUris.parseId(uri);SQLiteDatabase database = new MyDBHelper(this.getContext()).getReadableDatabase();if(database.isOpen()){database.execSQL("select * person where personid = "+id);return database.query("person", null, "personid", new String[]{id + ""}, null, null, null);//不要关闭数据库,否则就没有数据了. }case OTHER:Log.d(tag,"我是其他匹配规则!");break;default:throw new RuntimeException("出错了!!");}return null;}@Overridepublic String getType(Uri uri) {return null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {return null;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {return 0;}@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {return 0;} }
4.效果图
首先,将android_db部署到avd上,其次,运行android_content_provider项目,最后,查看log输出.
5.出现的问题
1).报空指针错误
.....at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at com.example.android_content_provider.ContentProvider.onCreate(ContentProvider.java:21) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) .....
这种问题很有可能是路径名称不对,注意提供的接口名称保持一致;并且保证获取数据的接口是正常的,即android_db里获取person表的内容是正常的.
2).intelij中的logcat中看不到log
注意选择Android--->选择要查看Log的进程--->点击上面的双向箭头进行切换日志展示信息.
6.扩展
1),查询,增加,删除,修改的接口全部实现
上面已经实现了查询的接口,这里将实现另外三个接口:
//4.插入数据,如果路径满足content://com.amos.android_db.provider.PersonProvider/insert,返回值就是(INSERT)=4uriMatcher.addURI("com.amos.android_db.provider.PersonProvider", "insert", INSERT);//5.删除数据,如果路径满足content://com.amos.android_db.provider.PersonProvider/delete,返回值就是(DELETE)=5uriMatcher.addURI("com.amos.android_db.provider.PersonProvider", "delete", DELETE);//6.更新数据,如果路径满足content://com.amos.android_db.provider.PersonProvider/update,返回值就是(UPDATE)=6uriMatcher.addURI("com.amos.android_db.provider.PersonProvider", "update", UPDATE);
对应的实现:
@Overridepublic Uri insert(Uri uri, ContentValues values) {//content://com.amos.android_db.provider.PersonProvider/insertint result = uriMatcher.match(uri);switch (result) {case INSERT:SQLiteDatabase database = myDBHelper.getWritableDatabase();if (database.isOpen()) {database.insert("person", null, values);}return uri;default:throw new RuntimeException("无法识别该URI,出错了!!");}}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {//删除操作//content://com.amos.android_db.provider.PersonProvider/deleteint result = uriMatcher.match(uri);switch (result) {case DELETE:SQLiteDatabase database = myDBHelper.getWritableDatabase();return database.delete("person", selection, selectionArgs);default:throw new RuntimeException("无法识别该URI,出错了!!");}}@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {//更新操作//content://com.amos.android_db.provider.PersonProvider/updateint result = uriMatcher.match(uri);switch (result) {case UPDATE:SQLiteDatabase database = myDBHelper.getWritableDatabase();return database.update("person", values, selection, selectionArgs);default:throw new RuntimeException("无法识别该URI,出错了!!");}}
//返回值的类型
@Overridepublic String getType(Uri uri) {int result = uriMatcher.match(uri);switch (result){case ALL_PERSON:return "List<Person>";case PERSON:return "Person";default:return null;}}
2)测试
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.ContentProviderTest"android:versionCode="1"android:versionName="1.0"><uses-sdk android:minSdkVersion="7"/><instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.ContentProviderTest"/><application android:label="@string/app_name"> <uses-library android:name="android.test.runner"/><activity android:name="MyActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application> </manifest>
加入加粗的两行,配置好测试的环境.
/ContentProviderTest/src/com/example/ContentProviderTest/test/TestCase.java
package com.example.ContentProviderTest.test;import android.content.ContentResolver; import android.content.ContentValues; import android.net.Uri; import android.test.AndroidTestCase;/*** Created by amosli on 14-6-19.*/ public class TestCase extends AndroidTestCase {public void testInsert(){ContentResolver contentResolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.amos.android_db.provider.PersonProvider/insert");ContentValues values = new ContentValues();values.put("name", "bill");values.put("age", 18);contentResolver.insert(uri, values);}public void testDelete(){ContentResolver contentResolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.amos.android_db.provider.PersonProvider/delete");contentResolver.delete(uri,"name=?",new String[]{"amos96"});}public void testUpdate(){ContentResolver contentResolver = getContext().getContentResolver();Uri uri = Uri.parse("content://com.amos.android_db.provider.PersonProvider/update");ContentValues contentValues = new ContentValues();contentValues.put("name","jack");contentValues.put("age",30);contentResolver.update(uri,contentValues,"name=?",new String[]{"amos97"});}}
3)效果图:
插入数据(insert方法),bill
删除数据(delete方法),amos96
更新数据(update方法 ),amos97
本文源码:
https://github.com/amosli/android_basic/tree/android_db
https://github.com/amosli/android_basic/tree/content_provoider
https://github.com/amosli/android_basic/tree/android_contentProviderTest
Android学习---通过内容提供者(ContentProvider)操作另外一个应用私有数据库的内容...相关推荐
- Android开发14——监听内容提供者ContentProvider的数据变化
一.提出需求 有A,B,C三个应用,B中的数据需要被共享,所以B中定义了内容提供者ContentProvider:A应用修改了B应用的数据,插入了一条数据.有这样一个需求,此时C应用需要得到数据被修改 ...
- Android学习笔记---20_采用ContentProvider对外共享数据, UriMatcher类使用介绍 ,ContentUris类使用介绍,使用ContentResolver操作Conte
20_采用ContentProvider对外共享数据 ------------------------------------------ 1.比如通讯录,就是通过ContentProvider,实现 ...
- Android内容提供者ContentProvider总结
一.ContentProvider基础知识 ContentProvider作为Android四大组件之一,相对其他组件来说,应用的场合是最少的了,但是它是有自己独特的作用的,比如为其他程序提供数据.C ...
- Android存储数据---内容提供者ContentProvider
简介 内容提供者的使用 2. 实例 (1)activity_main.xml <?xml version="1.0" encoding="utf-8"?& ...
- 内容提供者ContentProvider, 读写加联系人,读写通话记录,监听收到的短信,获取之前已经收到的短信
1.什么是内容提供者? 首先我们必须要明白的是ContentProvider(内容提供者)是android中的四大组件之一,但是在一般的开发中,可能使用比较少.ContentProvider为不同的软 ...
- 【Android学习之路】之从零开始做一个小项目(一)
最近在学Android(初学者吖),写下这个[Android学习之路]系列记录一下自己学习的过程,欢迎阅读~
- Android学习笔记---监听ContentProvider(内容共享者)中数据的变化
2013-03-16 监听ContentProvider中数据的变化 ------------------------------------------ 1.如果ContentProvider的访问 ...
- Android学习笔记十七.使用ContentProvider实现数据共享(四).操作系统(联系人)的ContentProvider
Android系统本身提供了大量的ContentProvider,例如联系人信息.系统的多媒体信息等,我们开发的应用程序主要是通过ContentResolver来调用系统的ContentPro ...
- Android学习笔记---13_文件的操作模式.各个应用之间的文件权限
2013-03-05 13_文件的操作模式 --------------------------------------- 1.注意在应用相同的情况下,不同的项目一定不要用相同的包名这样的话,会被视为 ...
最新文章
- 华人计算机视觉鼻祖、双院外籍院士黄煦涛逝世,昔日名师门徒遍天下
- 你的肠道菌群是遗传自你父母,还是后天环境塑造的?
- C语言的特点与执行程序基本步骤
- 【OpenCV学习】Bresenham算法opencv实现
- 【算法】均匀的生成圆内的随机点
- linux下使用TC模拟弱网络环境
- 2010年3月份第二周51aspx发布源码
- sqlserver的存储过程mysql_mysql,sqlserver存储过程的创建及执行
- 如何为 MySQL 选择 CPU?
- Servlet中将JavaBean对象传递到JSP页
- 小写和大写开头的英文名字 internet 和Internet在意思上有何重要区别?
- StudentManageSystem(学生管理系统)
- android显示每一年所有日期的功能,Android获取本周所有日期
- unity - 二进制文件操作-存储与读取
- 第二章 SQL命令参考-REASSIGN OWNED
- 自用笔记17——泰波那契数列
- 认识Excel的第五天(打印时固定标题)
- 论文总结3-Sub-center ArcFace: Boosting Face Recognition by Large-scale Noisy Web Faces
- 如何解决4G摄像头在智能巡检中掉线的方案
- wheel文件安装以及换源安装