使用ContentProvider共享数据
2015-06-09 23:13
691 查看
当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。
当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:
第二步需要在AndroidManifest.xml使用对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:
注意:一旦应用继承了ContentProvider类,后面我们就会把这个应用称为ContentProvider(内容提供者)。
下面通过案例来讲解:
新建名为db的Android Project
1.UserContentProvider.java
AndroidManifest.xml
HytcSQLiteOpenHelper.java
UserDao.java
使用ContentResolver操作ContentProvider中的数据
当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。
这些方法的第一个参数为Uri,代表要操作的是哪个ContentProvider和对其中的什么数据进行操作,假设给定的是: Uri.parse(“content://cn.csdn.provider.personprovider/person/10”),那么将会对主机名为cn.itcast.provider.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。
5. UserDaoTest.java
接下来新建另外一个Android Project,就可以访问该项目db的数据库。
当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:
public class PersonContentProvider extends ContentProvider{ public boolean onCreate() public Uri insert(Uri uri, ContentValues values) public int delete(Uri uri, String selection, String[] selectionArgs) public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) public String getType(Uri uri)}
第二步需要在AndroidManifest.xml使用对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:
<manifest .... > <application android:icon="@drawable/icon" android:label="@string/app_name"> <provider android:name=".PersonContentProvider" android:authorities="cncsdn.provider.personprovider"/> </application> </manifest>
注意:一旦应用继承了ContentProvider类,后面我们就会把这个应用称为ContentProvider(内容提供者)。
下面通过案例来讲解:
新建名为db的Android Project
1.UserContentProvider.java
package com.example.db.demo.provider; import com.example.db.demo.dao.UserDao; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.database.Cursor; import android.net.Uri; /** * 实现数据库共享的操作 * * @author Administrator * */ public class UserContentProvider extends ContentProvider { // 声明authory属性 private static final String USERCONTENTPROVIDER_AUTHORY = "com.example.db.provider.usercontentprovider"; // 定义uri操作的工具类uriMatcher private static UriMatcher uriMatcher; // 定义一些匹配的返回值 private static final int INSERT = 1; private static final int UPDATE = 2; private static final int DELETE = 3; private static final int QUERY = 4; private static final int QUERYS = 5; private static final int QUERYLASTDATA = 6; // 数据库操作对象 private UserDao userDao; /** * 默认构造函数 */ public UserContentProvider() { } // 静态初始化块 static { // UriMatcher类用于匹配Uri,第一步把你需要匹配Uri路径全部给注册上 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // 注册匹配规则 //插入的操作 uriMatcher.addURI(USERCONTENTPROVIDER_AUTHORY, "/insert", INSERT); // 更新的操作 uriMatcher.addURI(USERCONTENTPROVIDER_AUTHORY, "/update", UPDATE); // 删除的操作 uriMatcher.addURI(USERCONTENTPROVIDER_AUTHORY, "/delete", DELETE); // 查询操作 uriMatcher.addURI(USERCONTENTPROVIDER_AUTHORY, "/query/#", QUERY); // 查询操作 uriMatcher.addURI(USERCONTENTPROVIDER_AUTHORY, "/query", QUERYS); // 查询最后一条记录的uri的标识 uriMatcher.addURI(USERCONTENTPROVIDER_AUTHORY, "/query/last", QUERYLASTDATA); } /** * Android开机后, ContentProvider在其它应用第一次访问它时才会被创建 */ @Override public boolean onCreate() { userDao = new UserDao(getContext()); return false; } /** * 该方法用于供外部应用从ContentProvider中获取数据 */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor c = null; switch (uriMatcher.match(uri)) { case QUERY: long id = ContentUris.parseId(uri); c = userDao.query(new String[] { "_id", "name", "phone" }, "_id=?", new String[] { id + "" }, sortOrder); break; case QUERYS: c = userDao.query(new String[] { "_id", "name", "phone" }, null, null, sortOrder); break; case QUERYLASTDATA: c = userDao.queryLastData(new String[] { "_id", "name", "phone" }, null, null, sortOrder); break; } return c; } /** * 查询的操作的时候,告诉查询者 返回的是单个数据库 还是集合类型的数据 * 该方法用于返回当前Url所代表数据的MIME类型。如果操作的数据属于集合类型, * 那么MIME类型字符串应该以vnd.android.cursor.dir/开头 vnd.android.cursor.item/开头 */ @Override public String getType(Uri uri) { String result = ""; switch (uriMatcher.match(uri)) { case QUERY: result = "vnd.android.cursor.item/user"; break; case QUERYS: result = "vnd.android.cursor.dir/user"; break; } return result; } /** * 该方法用于供外部应用往ContentProvider添加数据。 */ @Override public Uri insert(Uri uri, ContentValues values) { // 实现一次插入 if (uriMatcher.match(uri) == INSERT) { long id = userDao.insert(values); // 告知调用者 我的数据发生了变化 getContext().getContentResolver().notifyChange(uri, null); return ContentUris.withAppendedId(uri, id); } else { throw new RuntimeException("uri不匹配,用户插入失败的操作"); } } /** * 该方法用于供外部应用从ContentProvider删除数据。 */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int rows = 0; // 实现一次插入 if (uriMatcher.match(uri) == DELETE) { rows = userDao.delete(selection, selectionArgs); } else { throw new RuntimeException("uri不匹配,用户删除失败"); } return rows; } /** * 该方法用于供外部应用更新ContentProvider中的数据。 */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int rows = 0; // 实现一次插入 if (uriMatcher.match(uri) == UPDATE) { rows = userDao.update(values, selection, selectionArgs); } else { throw new RuntimeException("uri不匹配,用户更新失败"); } return rows; } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.db" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.db" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 提供者 www.baidu.com www.sina.com --> <provider android:name="com.example.db.demo.provider.UserContentProvider" android:authorities="com.example.db.provider.usercontentprovider" android:exported="true" /> <uses-library android:name="android.test.runner" /> </application> </manifest>
HytcSQLiteOpenHelper.java
package com.example.db.demo; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class HytcSQLiteOpenHelper extends SQLiteOpenHelper { private static final String name = "hytc.db"; private static int version = 1; public HytcSQLiteOpenHelper(Context context) { super(context, name, null, version); } /** * 第一次执行 */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table user(_id integer primary key autoincrement,name varchar(50),phone varchar(11))"); } /** * 版本升级的时候 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } }
UserDao.java
package com.example.db.demo.dao; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.example.db.demo.HytcSQLiteOpenHelper; public class UserDao { private HytcSQLiteOpenHelper helper; private SQLiteDatabase db; public UserDao(Context context) { helper = new HytcSQLiteOpenHelper(context); System.out .println(helper + "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); } public long insert(ContentValues values) { // 获取数据库对象 db = helper.getWritableDatabase(); long id = db.insert("user", "name", values); db.close(); return id; } // 实现删除,更新,查询一个,查询所有 的操作 public int update(ContentValues values, String whereClause, String[] whereArgs) { // 获取数据库对象 db = helper.getWritableDatabase(); int rows = db.update("user", values, whereClause, whereArgs); db.close(); return rows; } public int delete(String whereClause, String[] whereArgs) { // 获取数据库对象 db = helper.getWritableDatabase(); int rows = db.delete("user", whereClause, whereArgs); db.close(); return rows; } public Cursor query(String[] projection, String selection, String[] selectionArgs, String sortOrder) { db = helper.getWritableDatabase(); return db.query("user", projection, selection, selectionArgs, null, null, sortOrder); } public Cursor queryLastData(String[] projection, String selection, String[] selectionArgs, String sortOrder) { db = helper.getWritableDatabase(); return db.query("user", projection, selection, selectionArgs, null, null, sortOrder, "1"); } }
使用ContentResolver操作ContentProvider中的数据
当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。
这些方法的第一个参数为Uri,代表要操作的是哪个ContentProvider和对其中的什么数据进行操作,假设给定的是: Uri.parse(“content://cn.csdn.provider.personprovider/person/10”),那么将会对主机名为cn.itcast.provider.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。
5. UserDaoTest.java
package com.example.db.demo.junit; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.test.AndroidTestCase; import com.example.db.demo.dao.UserDao; public class UserDaoTest extends AndroidTestCase { public void insertTest() { // userDao = new UserDao(getContext()); ContentValues values = new ContentValues(); values.put("name", "cttt11xx"); values.put("phone", "112"); // userDao.insert(values); ContentResolver resolver = getContext().getContentResolver(); Uri url = Uri .parse("content://com.example.db.provider.usercontentprovider/insert"); Uri resultUrl = resolver.insert(url, values); // 解析地址 long id = ContentUris.parseId(resultUrl); System.out.println(id); } public void updateTest() { // userDao = new UserDao(getContext()); ContentValues values = new ContentValues(); values.put("name", "chjxxttx"); values.put("phone", "1119090"); // userDao.insert(values); ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri .parse("content://com.example.db.provider.usercontentprovider/update"); int row = resolver .update(uri, values, "_id=?", new String[] { 4 + "" }); // 解析地址 if (row > 0) { System.out.println("更新成功"); } else { System.out.println("更新失败"); } } public void deleteTest() { // userDao = new UserDao(getContext()); ContentValues values = new ContentValues(); values.put("name", "chjxxttx"); values.put("phone", "1119090"); // userDao.insert(values); ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri .parse("content://com.example.db.provider.usercontentprovider/delete"); int row = resolver.delete(uri, "_id=?", new String[]{4+""}); // 解析地址 if (row > 0) { System.out.println("更新成功"); } else { System.out.println("更新失败"); } } public void queryByIdTest() { // userDao = new UserDao(getContext()); ContentValues values = new ContentValues(); values.put("name", "chjxxttx"); values.put("phone", "1119090"); // userDao.insert(values); ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri .parse("content://com.example.db.provider.usercontentprovider/query/2"); Cursor c = resolver.query(uri, null, null, null, null); // 解析地址 if(c.moveToNext()){ System.out.println(c.getInt(c.getColumnIndex("_id"))); System.out.println(c.getString(c.getColumnIndex("name"))); System.out.println(c.getString(c.getColumnIndex("phone"))); } c.close(); } public void queryTest() { // userDao = new UserDao(getContext()); ContentValues values = new ContentValues(); values.put("name", "chjxxttx"); values.put("phone", "1119090"); // userDao.insert(values); ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri .parse("content://com.example.db.provider.usercontentprovider/query"); Cursor c = resolver.query(uri, null, null, null, "_id desc"); // 解析地址 while(c.moveToNext()){ System.out.println(c.getInt(c.getColumnIndex("_id"))); System.out.println(c.getString(c.getColumnIndex("name"))); System.out.println(c.getString(c.getColumnIndex("phone"))); } c.close(); } public void queryLastData(){ UserDao userDao = new UserDao(getContext()); Cursor c = userDao.queryLastData(new String[]{"_id","name","phone"}, null, null, "_id desc"); // 解析地址 while(c.moveToNext()){ System.out.println(c.getInt(c.getColumnIndex("_id"))); System.out.println(c.getString(c.getColumnIndex("name"))); System.out.println(c.getString(c.getColumnIndex("phone"))); } c.close(); } public void queryLastData2() { // userDao = new UserDao(getContext()); ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri .parse("content://com.example.db.provider.usercontentprovider/query/last"); Cursor c = resolver.query(uri, null, null, null, "_id desc"); // 解析地址 while(c.moveToNext()){ System.out.println(c.getInt(c.getColumnIndex("_id"))); System.out.println(c.getString(c.getColumnIndex("name"))); System.out.println(c.getString(c.getColumnIndex("phone"))); } c.close(); } }
接下来新建另外一个Android Project,就可以访问该项目db的数据库。
相关文章推荐
- Yii 自定义表单验证规则和客户端验证
- Yii2基于角色的访问控制权限RBAC表结构原理分析
- php扩展开发笔记(4)常用宏整理(更新中)
- PrintDocument,PrintDialog与PrintPreviewDialog
- Yii2验证器(Validator)
- 用smtplib登录qq邮箱发邮件
- PHP设计模式——中介者模式
- Yii2中多表关联查询(join、joinwith)
- 解决Notice错误,性能竟然提升了1000多倍!
- Yii学习笔记之三(在windows 上安装 advanced )
- thinkphp使用flash上传验证登录问题
- Yii2 使用十七 国际化
- Yii学习笔记之二(使用gii生成一个简单的例子)
- php实现工厂模式
- getParameter
- php脚本超时时间设置
- PHP-获取上周一周的日期
- PHP array_diff()
- 欢迎使用CSDN-markdown编辑器
- thinkphp 自动验证 demo(自用)