一.什么是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)操作另外一个应用私有数据库的内容...相关推荐

  1. Android开发14——监听内容提供者ContentProvider的数据变化

    一.提出需求 有A,B,C三个应用,B中的数据需要被共享,所以B中定义了内容提供者ContentProvider:A应用修改了B应用的数据,插入了一条数据.有这样一个需求,此时C应用需要得到数据被修改 ...

  2. Android学习笔记---20_采用ContentProvider对外共享数据, UriMatcher类使用介绍 ,ContentUris类使用介绍,使用ContentResolver操作Conte

    20_采用ContentProvider对外共享数据 ------------------------------------------ 1.比如通讯录,就是通过ContentProvider,实现 ...

  3. Android内容提供者ContentProvider总结

    一.ContentProvider基础知识 ContentProvider作为Android四大组件之一,相对其他组件来说,应用的场合是最少的了,但是它是有自己独特的作用的,比如为其他程序提供数据.C ...

  4. Android存储数据---内容提供者ContentProvider

    简介 内容提供者的使用 2. 实例 (1)activity_main.xml <?xml version="1.0" encoding="utf-8"?& ...

  5. 内容提供者ContentProvider, 读写加联系人,读写通话记录,监听收到的短信,获取之前已经收到的短信

    1.什么是内容提供者? 首先我们必须要明白的是ContentProvider(内容提供者)是android中的四大组件之一,但是在一般的开发中,可能使用比较少.ContentProvider为不同的软 ...

  6. 【Android学习之路】之从零开始做一个小项目(一)

    最近在学Android(初学者吖),写下这个[Android学习之路]系列记录一下自己学习的过程,欢迎阅读~

  7. Android学习笔记---监听ContentProvider(内容共享者)中数据的变化

    2013-03-16 监听ContentProvider中数据的变化 ------------------------------------------ 1.如果ContentProvider的访问 ...

  8. Android学习笔记十七.使用ContentProvider实现数据共享(四).操作系统(联系人)的ContentProvider

        Android系统本身提供了大量的ContentProvider,例如联系人信息.系统的多媒体信息等,我们开发的应用程序主要是通过ContentResolver来调用系统的ContentPro ...

  9. Android学习笔记---13_文件的操作模式.各个应用之间的文件权限

    2013-03-05 13_文件的操作模式 --------------------------------------- 1.注意在应用相同的情况下,不同的项目一定不要用相同的包名这样的话,会被视为 ...

最新文章

  1. 华人计算机视觉鼻祖、双院外籍院士黄煦涛逝世,昔日名师门徒遍天下
  2. 你的肠道菌群是遗传自你父母,还是后天环境塑造的?
  3. C语言的特点与执行程序基本步骤
  4. 【OpenCV学习】Bresenham算法opencv实现
  5. 【算法】均匀的生成圆内的随机点
  6. linux下使用TC模拟弱网络环境
  7. 2010年3月份第二周51aspx发布源码
  8. sqlserver的存储过程mysql_mysql,sqlserver存储过程的创建及执行
  9. 如何为 MySQL 选择 CPU?
  10. Servlet中将JavaBean对象传递到JSP页
  11. 小写和大写开头的英文名字  internet 和Internet在意思上有何重要区别?
  12. StudentManageSystem(学生管理系统)
  13. android显示每一年所有日期的功能,Android获取本周所有日期
  14. unity - 二进制文件操作-存储与读取
  15. 第二章 SQL命令参考-REASSIGN OWNED
  16. 自用笔记17——泰波那契数列
  17. 认识Excel的第五天(打印时固定标题)
  18. 论文总结3-Sub-center ArcFace: Boosting Face Recognition by Large-scale Noisy Web Faces
  19. 如何解决4G摄像头在智能巡检中掉线的方案
  20. wheel文件安装以及换源安装

热门文章

  1. golang导入包的理解
  2. Spring mvc Interceptor 解决Session超时配置流程
  3. Centos VMware 克隆后 网络配置
  4. java 常用集合list与Set、Map区别及适用场景总结
  5. 机器视觉的典型应用及领域分析
  6. CGCS2000 VS WGS84
  7. ​EMC存储产品介绍分析(二):大数据利器Isilon (2)
  8. 分众传媒的连夜雨和消化不良症
  9. 《Java程序设计》第4周学习总结
  10. eclipse图标含义