- 浏览: 152096 次
- 性别:
- 来自: 湖南
文章分类
最新评论
-
viking_wu:
Android POST方式提交数据 -
hsiunien:
不能正常调用 init android4.3上 是否可以 ...
Android JS双向调用 -
liaokang.java:
Apple.Chen 写道你确定这是插入排序而不是冒泡?插入排 ...
java之插入排序 -
Apple.Chen:
你确定这是插入排序而不是冒泡?
java之插入排序 -
ct19900913:
顶一个!!!
Android ContentProvider共享数据
ContentProvider的基本概念
a.ContentProvider为存储和读取数据提供了统一的接口
b.使用ContentProvider,应用程序可以实现数据共享
c.android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)
1.数据模型
Content Provider 将其存储的数据以数据表的形式提供给访问者,在数据表中每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个 "_ID" 数值字段,改字段唯一标识一条数据。
2.Uri
Uri,每一个Content Provider 都对外提供一个能够唯一标识自己数据集(dataset)的公开URI, 如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider 的URI 都以"content://" 开头,其中"content:"是用来标识数据是由Content Provider管理的 schema。
在几乎所有的Content Provider 的操作中都会用到Uri,因此一般来讲,如果是自己开发的Content Provider,最好将URI定义为常量,这样在简化开发的同时也提高了代码的可维护性。
我们将Uri分为A,B,C,D 4个部分:
A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的"content://"
B:Uri的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的,小写的类名。这个标识在元素的authorities属性中说明:一般是定义该ContentProvider的包.类的名称,如"content://com.lamp.provider.personprovider"
C:路径,Uri下的某一个Item,就像网站一样,主网页下包含很多小网页。这里通俗的讲就是你要操作的数据库中表的名字(比如我操作的表为person),或者你也可以自己定义,记得在使用的时候保持一致就ok了,如"content://com.lamp.provider.personprovider/person"
D:如果Uri中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示对全部记录进行操作,例如content://com.lamp.provider.personprovider/person 针对表中所有记录
content://com.lamp.provider.personprovider/person/5 针对id为5的记录
UriMatcher:用于匹配Uri,它的用法如下:
1.首先把你需要匹配Uri路径全部给注册上。
1.常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
2.注册匹配的Uri
//content://com.lamp.provider.personprovider/person 针对表中所有记录,如果匹配该路径,返回1
uriMatcher.addURI(authority, "person", 1);
//content://com.lamp.provider.personprovider/person/# 针对符合条件的记录,如果匹配该路径,返回2
uriMatcher.addURI(authority, "person/#",2);
3.注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹 配就返回匹配码,匹配码是调用 addURI()方法传入的第三个参数,假设匹配 content://com.lamp.provider.personprovider/person 路径,返回的匹配码为1。
ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分
parseId(uri)方法用于从路径中获取ID部分
下面是一个小例子来说明ContentProvider的使用
1.新建一个类来继承ContentProvider
2.在AndroidManifest.xml对ContentProvider进行配置,为了能使其它应用能找到该ContentProvider,ContentProvider采用了android:authorities对它进行唯一标识,你可以把ContentProvider看成是一个网站,authorities就是它的域名
3.由于我操作的数据是针对数据库,新建一个类继承SQLiteOpenHelper
4.用到的实体bean为Person
至此ContentProvider的配置完成,将项目部署到模拟器或者手机中,下面来编写一个新的应用来对上一个应用的数据进行测试
1.新建一个新的项目
记得在AndroidManifest.xml中注册权限
a.ContentProvider为存储和读取数据提供了统一的接口
b.使用ContentProvider,应用程序可以实现数据共享
c.android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)
1.数据模型
Content Provider 将其存储的数据以数据表的形式提供给访问者,在数据表中每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个 "_ID" 数值字段,改字段唯一标识一条数据。
2.Uri
Uri,每一个Content Provider 都对外提供一个能够唯一标识自己数据集(dataset)的公开URI, 如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider 的URI 都以"content://" 开头,其中"content:"是用来标识数据是由Content Provider管理的 schema。
在几乎所有的Content Provider 的操作中都会用到Uri,因此一般来讲,如果是自己开发的Content Provider,最好将URI定义为常量,这样在简化开发的同时也提高了代码的可维护性。
我们将Uri分为A,B,C,D 4个部分:
A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的"content://"
B:Uri的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的,小写的类名。这个标识在元素的authorities属性中说明:一般是定义该ContentProvider的包.类的名称,如"content://com.lamp.provider.personprovider"
C:路径,Uri下的某一个Item,就像网站一样,主网页下包含很多小网页。这里通俗的讲就是你要操作的数据库中表的名字(比如我操作的表为person),或者你也可以自己定义,记得在使用的时候保持一致就ok了,如"content://com.lamp.provider.personprovider/person"
D:如果Uri中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示对全部记录进行操作,例如content://com.lamp.provider.personprovider/person 针对表中所有记录
content://com.lamp.provider.personprovider/person/5 针对id为5的记录
UriMatcher:用于匹配Uri,它的用法如下:
1.首先把你需要匹配Uri路径全部给注册上。
1.常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
2.注册匹配的Uri
//content://com.lamp.provider.personprovider/person 针对表中所有记录,如果匹配该路径,返回1
uriMatcher.addURI(authority, "person", 1);
//content://com.lamp.provider.personprovider/person/# 针对符合条件的记录,如果匹配该路径,返回2
uriMatcher.addURI(authority, "person/#",2);
3.注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹 配就返回匹配码,匹配码是调用 addURI()方法传入的第三个参数,假设匹配 content://com.lamp.provider.personprovider/person 路径,返回的匹配码为1。
ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分
parseId(uri)方法用于从路径中获取ID部分
下面是一个小例子来说明ContentProvider的使用
1.新建一个类来继承ContentProvider
package com.lamp.db; 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.text.TextUtils; import com.lamp.service.DataBaseOpenHelper; public class PersonContentProvider extends ContentProvider { private DataBaseOpenHelper dbHelper = null; private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); private static final int ALLPERSON = 1; private static final int PERSON = 2; private static final String authority = "com.lamp.provider.personprovider"; private static String TABLENAME = "person"; static{ //content://com.lamp.provider.personprovider/person 针对表中所有记录,如果匹配该路径,返回1 uriMatcher.addURI(authority, TABLENAME, ALLPERSON); //content://com.lamp.provider.personprovider/person/# 针对符合条件的记录,如果匹配该路径,返回2 uriMatcher.addURI(authority, TABLENAME + "/#", PERSON); } @Override public boolean onCreate() { dbHelper = new DataBaseOpenHelper(this.getContext()); return true; } //删除数据 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase database = dbHelper.getWritableDatabase(); int count = 0; switch (uriMatcher.match(uri)) { case ALLPERSON: count = database.delete(TABLENAME, selection, selectionArgs); break; case PERSON: long personid = ContentUris.parseId(uri); String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?"; String[] params = new String[]{String.valueOf(personid)}; if(!TextUtils.isEmpty(selection) && selectionArgs!=null){ params = new String[selectionArgs.length+1]; for (int i = 0; i < selectionArgs.length; i++) { params[i] = selectionArgs[i]; } params[selectionArgs.length] = String.valueOf(personid); } count = database.delete(TABLENAME, where, params); break; default: throw new IllegalArgumentException("参数错误" + uri); } return count; } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case ALLPERSON: return "vnd.android.cursor.dir/personprovider.person"; case PERSON: return "vnd.android.cursor.item/personprovider.person"; default: throw new IllegalArgumentException("参数错误" + uri); } } //插入数据 @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase database = dbHelper.getWritableDatabase(); long id = 0; switch (uriMatcher.match(uri)) { case ALLPERSON: id = database.insert(TABLENAME, "name", values); return ContentUris.withAppendedId(uri, id); case PERSON: id = database.insert(TABLENAME, "name", values); String uriString = uri.toString(); uriString = uriString.substring(0, uriString.lastIndexOf("/")) + id; return Uri.parse(uriString); default: throw new IllegalArgumentException("参数错误" + uri); } } //查询数据 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase database = dbHelper.getWritableDatabase(); switch (uriMatcher.match(uri)) { case ALLPERSON: return database.query(TABLENAME, projection, selection, selectionArgs, null, null, sortOrder); case PERSON: long personid = ContentUris.parseId(uri); String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?"; String[] params = new String[]{String.valueOf(personid)}; if(!TextUtils.isEmpty(selection) && selectionArgs!=null){ params = new String[selectionArgs.length+1]; for (int i = 0; i < selectionArgs.length; i++) { params[i] = selectionArgs[i]; } params[selectionArgs.length] = String.valueOf(personid); } return database.query(TABLENAME, projection, where, params, null, null, sortOrder); default: throw new IllegalArgumentException("参数错误" + uri); } } //更新数据 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase database = dbHelper.getWritableDatabase(); int count = 0; switch (uriMatcher.match(uri)) { case ALLPERSON: count = database.update(TABLENAME, values, selection, selectionArgs); break; case PERSON: long personid = ContentUris.parseId(uri); String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?"; String[] params = new String[]{String.valueOf(personid)}; if(!TextUtils.isEmpty(selection) && selectionArgs!=null){ params = new String[selectionArgs.length+1]; for (int i = 0; i < selectionArgs.length; i++) { params[i] = selectionArgs[i]; } params[selectionArgs.length] = String.valueOf(personid); } count = database.update(TABLENAME, values, where, params); break; default: throw new IllegalArgumentException("参数错误" + uri); } return count; } }
2.在AndroidManifest.xml对ContentProvider进行配置,为了能使其它应用能找到该ContentProvider,ContentProvider采用了android:authorities对它进行唯一标识,你可以把ContentProvider看成是一个网站,authorities就是它的域名
<application android:icon="@drawable/icon" android:label="@string/app_name"> <uses-library android:name="android.test.runner" /> <provider android:name=".PersonContentProvider" android:authorities="com.lamp.provider.personprovider"/> .....
3.由于我操作的数据是针对数据库,新建一个类继承SQLiteOpenHelper
package com.lamp.service; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DataBaseOpenHelper extends SQLiteOpenHelper { private static final String DBNAME = "android"; private static final int VERSION = 1; public DataBaseOpenHelper(Context context) { super(context, DBNAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { String sql = "create table person (personid integer primary key autoincrement,name varchar(20),age integer)"; sqLiteDatabase.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { String sql = "drop table if exists person"; sqLiteDatabase.execSQL(sql); onCreate(sqLiteDatabase); } }
4.用到的实体bean为Person
package com.lamp.domain; public class Person { private Integer personid = null; private String name = null; private Integer age = null; public Person() { } public Person(String name,Integer age){ this.name = name; this.age = age; } public Integer getPersonid() { return personid; } public void setPersonid(Integer personid) { this.personid = personid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "personid:" + this.personid + "name: " + this.name + ", age:" + this.age; } }
至此ContentProvider的配置完成,将项目部署到模拟器或者手机中,下面来编写一个新的应用来对上一个应用的数据进行测试
1.新建一个新的项目
package com.lamp.provider; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.net.Uri; import android.os.Bundle; import android.util.Log; public class PersonProviderTestActivity extends Activity { private static final String TAG = "PersonProviderTestActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ContentResolver cr = this.getContentResolver(); //通过唯一的Uri对特定的应用进行数据的操作 Uri uri = Uri.parse("content://com.lamp.provider.personprovider/person"); //插入数据 /* uri = Uri.parse("content://com.lamp.provider.personprovider/person"); ContentValues values = new ContentValues(); values.put("name", "kang"); values.put("age", 35); Uri uris = cr.insert(uri, values); */ //查询数据,此处是查询personid=13的记录 /* Uri uri = Uri.parse("content://com.lamp.provider.personprovider/person/13"); Cursor cursor = cr.query(uri, new String[]{"personid","name","age"}, null, null, null); while(cursor.moveToNext()){ Log.i(TAG, cursor.getInt(0) + " name:" + cursor.getString(1)); } cursor.close();*/ //测试删除,此处是删除personid=10的记录 uri = Uri.parse("content://com.lamp.provider.personprovider/person/10"); int count = cr.delete(uri, null, null); Log.i(TAG, String.valueOf(count)); //测试更新,此处是更新personid=14的记录 /* uri = Uri.parse("content://com.lamp.provider.personprovider/person/14"); ContentValues values2 = new ContentValues(); values2.put("name", "aaaaa"); values2.put("age", 35); int count = cr.update(uri, values2, null, null); Log.i(TAG, String.valueOf(count)); */ } }
记得在AndroidManifest.xml中注册权限
<uses-permission android:name="android.permission.READ_CONTACTS" />
发表评论
-
Android JS双向调用
2011-09-08 21:29 31396Android手机中内置了一款高性能webkit内核,该内核完 ... -
Android 音频播放
2011-09-08 10:22 2008android音频播放方式有两种:一种是MediaPlayer ... -
Android 流方式发送XML数据
2011-09-06 14:10 2520我们可以采用请求参数的形式向服务器发送数据,但是当数据太大时, ... -
Android POST方式提交数据
2011-09-05 19:53 12967android虽然内置了apache的 ... -
Android ListView详解
2011-08-31 22:18 1791在android应用中,数据以列表的形式显示通常是通过List ... -
Android采用Pull解析和生成xml文档
2011-08-29 19:03 2295Pull解析和Sax解析很相似,都是轻量级的解析,在Andro ... -
Android SAX解析xml文件
2011-08-28 18:39 1033andorid读取xml文件内容方法有三种 sax dom p ... -
Android之拨号器
2011-08-27 00:09 1361下面是用Android模拟拨号的小例子 首先是布局文件main ... -
Android之短信发送器
2011-08-27 00:03 954虽然手机内置了短信发送器,但是有时候为了特定的需求项目 ...
相关推荐
ContentProvider数据共享的基本使用方法
Android高级编程雪梨作业之自定义ContentProvider 将任务01生词本作业中生成的生词本数据库通过自定义ContentProvider的方式,共享给其他应用。 要求如下: (1) 使用自定义SQLiteOpenHelper来管理数据库; (2) 提交...
此demo利用ContentProvider实现android app间的数据共享
图1 图2代码都通过文件夹分类首先是内容提供者Lab8ContentProvider(应用一)还有SQL的HELPER:SQLiteUtil对应注册清单文件<p
ContentProvider(数据提供者)是在应用程序间共享数据的一种接口机制。应用程序在不同的进程中运行,因此,数据和文件在不同应用程序之间是不能够直接访问的。
疯狂android资料:第九章使用ContentProvider实现数据共享.doc
Android应用程序组件Content Provider的共享数据更新通知机制分析
ContentProvider实现数据共享
ContentProvider 实例,实现ContentProvider,从其他应用访问ContentProvider数据,实现资源共享
1.适用场景1) ContentProvider为存储和读取数据提供了...虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferen
安卓程序间数据共享的实现,包含两个程序,共享资源的程序和读取资源的程序,共享资源的程序包含了SQLite数据库的使用。
android ContentProvider 不用应用程序的数据共享,数据的存储方式
android-关于ContentProvider的使用例子 有详细注释
ContentProvider 与 ContentResovler 进行应用间数据共享
android2.3以及以下版本的跨应用数据调用,通过sharepreference实现
通过contentprovider实现不同程序之间的数据共享
代码非常乱 就有一个大框 仅供自己学习用