ContentProvider的使用
2016-06-12 19:08
369 查看
ContentProvider的使用
ContentProvider是Android的四大组件之一,他可以把自己的数据暴漏出来,让其他应用可以对该数据进行增删改查,若应用程序通过内容提供者暴漏了自己的数据,则无论该应用程序是否启动了,其他应用程序都可通过该接口来操作数据。内容提供者操作的数据可以是数据库数据也可以是文件等他存储方式,如要操作xml文件中user节点下的name节点,通过ContentResolver操作内容提供者,Uri是提供者和操作者之间进行数据交换的标识,通过系统找到对应的ContentProvider,ContentResolver的操作实际是Uri对应的ContentProvider实现的对数据的操作,执行的提供者中的增删改查,ContentResolver执行的insert(),delete(),update(),query()实际是ContentProvider执行的对应的方法,最终执行的都是在内容提供者中。
内容提供者在应用中多以单例模式使用
ContentProvider的使用:
1.内容提供者
(1) 定义类继承ContentProvider基类,重写方法
(2) 在清单文件中注册,注册时需要指定authorities,该属性用于其他应用找到该内容提供者的标记,从而进行操作数据,并设置为可供外部应用调用(exported)
内容提供者的方法:
创建时调用的方法:Oncreate():该方法在内容提供者创建后会被调用,当其他应用第一次访问内容提供者时调用
插入数据时调用的方法 :PublicUri insert(Uri uri,ContentValues values);第一个参数是插入数据的uri地址标记,第二个参数是插入的数据
删除数据时调用的方法:publicint delete(Uri uri,String selection, String[] selectionArgs);//第一个参数是操作的地址,第二个参数是删除的数据的where条件,第三个参数是第二个参数中的条件中的值
更新时调用的方法:public intupdata(Uri uri,ContentValues values,String selection,String[] selectionArgs);//第一个参数是操作的数据的位置,第二参数是根据条件找到的数据修改后的结果,第三个参数是更新数据的条件,第三个参数是更新条件中的?对应的值
查询时调用的方法:publicCursor query(Uri uri,String[] projection,String selection,String[]selectionArgs,String sortOrder);//第一个参数是查询数据的地址,第二个参数是筛选返回的结果,第三个参数是查询的条件不需要则为null,第四个参数是查询条件中的?所指代的数值,第五个参数是查询出的数据的排列方式,是升序或降序。
PublicString getType(Uri uri):该方法用于放回当前Uri所代表的MIME类型,若该Uri对应的数据可能包含多条记录,则MIME类型字符串应该以vnd.android.cursor.dir/开头,若只有一天记录则以vnd.android.cursor.item/开头
2.内容操作者
ContentResolver是用于操作内容提供者提供的数据,在其他应用中通过ContentResolver修改提供的数据。每个方法的返回值的类型就是内容提供者中对应的方法的返回值,执行的也是对应的提供者中的方法。
Context的getContentReslover(),获取ContentReslover对象。
Insert(Uri,ContentValues);//向对应的内容提供者中插入ContentValues的数据。
delete(Uri,String where,String[] selectionArgs);//删除uri对应的内容提供者中的数据,查找条件是where,where中的参数的值是selectionArgs
update(Uri,ContentValues,String where,String[] selectionArgs);//修改uri对应的内容提供者中根据条件找到的数据成ContentValues数据
quert(Uri,String[] projection,String selection,String[]selectionArgs,String sortOrder);查询内容提供者中查询出的数据返回cursor
3.Uri介绍
Uri相当于网络的网址,用于指定操作的位置,Uri分为3部分
以content://org.crazyit.providers.dictproviders/words为例
content://:这是固定的开头,相当于URl中的http://
org.crazyit.providers.dictproviders:这个部分是内容提供者注册中的authorities,通过该部分找到操作的内容提供者,相当于URl中的域名部分
words://:数据部分,相当于URl中的具体文件部分
4.UriMatcher介绍
UriMatcher是用于对uri进行匹配,多使用于在内容提供者中进行增删改查操作时对uri进行匹配,通过匹配进行区分操作,
方法:
addURI(authority,path, code)//第一个参数对内容提供者而言是内容提供者中注册时的authorities属性规定的内容提供者的标记,第二个参数是操作的表名,第三个参数是匹配码,当进行匹配是方法返回的值
match(Uri);进行匹配时调用的方法
5. ContentUri
Uri的工具类,多用于对uri和数据id的添加和解析操作,例如内容提供者中数据操作成功后,返回的uri是插入数据后的添加id后的uri可通过下面的方法进行操作: withAppendedld(uri,id);//将一个id添加到一个uri的末尾形成一个新的uri
parseId(uri);//用于指出一个uri中所包含的id
使用例子:
实体类:
public
classWords {
public
final static String authority="com.myContentProvider";
public
static final
class Word{
public
final static String id="id";
public
final static String word="word";
public
final static String detail="detail";
public
final static Uri urione=Uri.parse("content://com.myContentProvider/words");
public
final static Uri uritwo=Uri.parse("content://com.myContentProvider/word");
}
}
其中一个应用中定义的内容提供者
public
classMyContentProvider extends ContentProvider{
private
staticUriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);//uri匹配器,添加多个Uri则可以匹配多个,其中有匹配码可以用于匹配后返回的值
private
staticfinalintWORES=1;
private
staticfinalintWORD=2;
private
staticfinalintWORDD=4;
private
staticfinalintWORDDS=5;
private Heplpter
heplpter;
//当第一次调用内容提供者时调用,只调用一次
@Override
public
boolean onCreate() {
heplpter=new Heplpter(this.getContext(),
"EnglishDB.db",null,1);//拿到数据库对象就可以对数据库增删改查了
matcher.addURI(Words.authority,
"English",WORES);//用于操作English表,对数据库而言第二个参数是表名,第一个参数是本内容提供者的zuthorities属性,第三个数据是uri的匹配码,当执行增删改查操作的时候,就是通过matcher匹配uri返回的值:相当于content://authorities/表名/id
matcher.addURI(Words.authority,
"English/#",WORD);//用于操作English表的多条数据的匹配//English/#代表的是English表下的某一条数据,使用于列表点击某条查询某条的数据,
matcher.addURI(Words.authority,
"Englishdd",WORDD);//用于操作Englishdd表的多条数据的匹配
matcher.addURI(Words.authority,
"Englishdd/#",WORDD);//用于操作Englishdd表的单条数据的匹配
return
true;
}
//返回uri所代表的数据的mime类型,若uri对应的数据可能包含多条记录,则mime类型字符串应该以vnd.android.cursor.dir/开头,若只包含一条记录,则对应的应该是vnd.android.cursor.item/开头
@Override
public String getType(Uri uri){
//若操作的是集合类型则返回WORDS,若只有一条数据则返回WORD下的数据
switch(matcher.match(uri)){
case
WORES:
return
"vnd.android.cursor.dir./English";//dir是目录的意思,意思是返回English表的集合,这个的返回是根据我们操作的数据返回的结果是一条数据还是一个集合
case
WORD:
return
"vnd.android.cursor.item./English";//item是项的意思,意思是返回English表的某一线,这个的返回是根据我们操作的数据返回的结果是一条数据还是一个集合
case
WORDD:
return
"vnd.android.cursor.dir./Englishdd";//dir是目录的意思,意思是返回Englishdd表的集合,这个的返回是根据我们操作的数据返回的结果是一条数据还是一个集合
case
WORDDS:
return
"vnd.android.cursor.item./Englishdd";//item是项的意思,意思是返回Englishdd表的某一线,这个的返回是根据我们操作的数据返回的结果是一条数据还是一个集合
default:
throw
newIllegalArgumentException("未知Uri:"+uri);
}
}
//根据uri删除selection条件匹配的所有记录
@Override
public
int delete(Uri uri, Stringselection, String[] selectionArgs) {
SQLiteDatabasedb=heplpter.getWritableDatabase();
int num=0;
//uri可能有多个,//下面这个就是对uri进行分类,
switch(matcher.match(uri)){
case
WORES:
num=db.delete("English",selection, selectionArgs);
break;
case
WORD:
long id=ContentUris.parseId(uri);
StringwhereClause=Words.Word.id+"="+id;//id=2的数据
if(selection!=null&&!"".equals(selection)){
whereClause=whereClause+"and"+selection;//拼接条件
}
num=db.delete("English",whereClause, selectionArgs);
break;
default:
throw
newIllegalArgumentException("未知Uri:"+uri);
}
getContext().getContentResolver().notifyChange(uri,null);
db.close();
return num;
}
//根据uri插入对应values数据
@Override
public Uri insert(Uri uri,ContentValues values) {
SQLiteDatabasedb=heplpter.getWritableDatabase();
switch(matcher.match(uri)){
case
WORES:
long rowId=db.insert("English",Words.Word.id,values);//返回值是插入数据的行id
if(rowId>0){
UriwordUri=ContentUris.withAppendedId(uri, rowId);
getContext().getContentResolver().notifyChange(wordUri,null);
db.close();
return wordUri;//插入成功后返回的是插入数据的uri
}
break;
default:
db.close();
throw
newIllegalArgumentException("未知Uri:"+uri);
}
return
null;
}
//根据uri查询出selection条件所匹配的所有记录,,projection是一个列表名,表明只选择出指定的数据列。
@Override
public Cursor query(Uri uri,String[] projection, String selection, String[] sectionArgs,
StringsortOrder) {
SQLiteDatabasedb=heplpter.getWritableDatabase();
Cursorcursor=null;
switch(matcher.match(uri)){
case
WORES:
cursor=db.query("English",projection, selection, sectionArgs,
null, null, sortOrder);
// db.close();
return cursor;
case
WORD:
long id=ContentUris.parseId(uri);
StringwhereClause=Words.Word.id+"="+id;
if(selection!=null&&!"".equals(selection)){
whereClause=whereClause+"and"+selection;
}
cursor=db.query("English",projection, selection, sectionArgs,
null, null, sortOrder);
// db.close();//不能关闭数据库
return cursor;
default:
throw
newIllegalArgumentException("未知Uri:"+uri);
}
}
//根据uri修改selection条件匹配的记录
@Override
public
int update(Uri uri,ContentValues values, String selection, String[] selectionArgds) {
SQLiteDatabasedb=heplpter.getWritableDatabase();
int num=0;
switch(matcher.match(uri)){
case
WORES:
num=db.update("English",values, selection, selectionArgds);
break;
case
WORD:
long id=ContentUris.parseId(uri);
StringwhereClause=Words.Word.id+"="+id;
if(selection!=null&&!"".equals(selection)){
whereClause=whereClause+"and"+selection;
}
num=db.update("English",values, whereClause, selectionArgds);
break;
default:
throw
newIllegalArgumentException("未知Uri:"+uri);
}
getContext().getContentResolver().notifyChange(uri,null);
db.close();
return num;
}
}
SQLiteOpenHelpter:
public class Heplpter extends SQLiteOpenHelper{
//name是创建的数据库的名称后缀是.db,factory是Cursor工厂可以写null为默认的工厂,vertsion是数据库的版本
publicHeplpter(Context context, String name, CursorFactory factory,
intversion) {
super(context,name, factory, version);//使用默认的cursorFactory
}
//当调用getWritableDatabase()(以写的方式打开数据库,若数据库的磁盘空间慢了,数据库则只能读不能写了,此时用本方法打开则会报错)或getReadablDatabase()(先以读写的方式打开数据库,若数据库的磁盘空间慢了,此时打开数据库就会打开失败,则会以只读的方式打开数据库)方法获取数据库对象时调用,若不存在数据库则系统或自动创建爱一个在调用oncreate(),其中自动创建一个表,用于操作数据
@Override
publicvoid onCreate(SQLiteDatabase db) {
db.execSQL("createtable English(id integer primary key autoincrement,word varchar(255),detailvarchar(255))");//执行sql语句
}
//当版本变化时调用,当创建本实例对象时会传入一个version,该version高于之前的版本号则会调用.
@Override
publicvoid onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// publicHeplpter getInstance(){
// returnnew
// }
}
//清单注册:
<provider
android:name="com.example.sharecontent.mycontentprovider.MyContentProvider"
android:authorities="com.myContentProvider"
android:exported="true"
></provider>
//另一个应用的使用ContentResolver
另一个应用布局
<?xml
version="1.0"encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
>
<Button
android:id="@+id/insert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="插入数据"
/>
<Button
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除数据"
/>
<Button
android:id="@+id/update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改数据"
/>
<Button
android:id="@+id/query"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询数据"
/>
<EditText
android:id="@+id/change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="修改数据或查询数据的字段"
/>
<EditText
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="文字描述"
/>
<EditText
android:id="@+id/willChange"
android:layout_width="match_parent"
android:layout_height="40dp"
android:hint="请输入将被修改的词"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical"
>
<ListView
android:id="@+id/showWords"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
</LinearLayout>
另一个应用的类
public
classShowMessage extends Activity{
EditTextchange;
EditTextcontent;
ListViewshowWords;
ArrayAdapteradapter;
List<String>listWords;
EditTextwillChange;
@Override
protected
void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_showmessage);
willChange=(EditText)findViewById(R.id.willChange);
Buttoninsert=(Button) findViewById(R.id.insert);
Buttondelete=(Button) findViewById(R.id.delete);
Buttonupdate=(Button) findViewById(R.id.update);
Buttonquery=(Button) findViewById(R.id.query);
change=(EditText)findViewById(R.id.change);
content=(EditText)findViewById(R.id.content);
showWords=(ListView)findViewById(R.id.showWords);
final ContentResolverresolver=getContentResolver();
final Uri uri=Uri.parse("content://com.myContentProvider/English");//通過uri找到內容提供者
insert.setOnClickListener(new View.OnClickListener(){
@Override
public
void onClick(View arg0) {
Stringword=change.getText().toString();
Stringcontents=content.getText().toString();
ContentValuesvalues=newContentValues();
values.put("word", word);
values.put("detail",contents);
Uriuris=resolver.insert(uri, values);
Toast.makeText(ShowMessage.this,
"添加成功后的uri是"+uris, Toast.LENGTH_SHORT).show();
}
});
delete.setOnClickListener(new View.OnClickListener(){
@Override
public
void onClick(View arg0) {
Stringword=change.getText().toString();
// intid=resolver.delete(uri, "", null);//删除uri指定的数据
int id=resolver.delete(uri,"word=?",newString[]{word});
Toast.makeText(ShowMessage.this,
"删除的是数据"+id, Toast.LENGTH_SHORT).show();
}
});
update.setOnClickListener(new View.OnClickListener(){
@Override
public
void onClick(View arg0) {
Stringword=change.getText().toString();
Stringcontents=content.getText().toString();
Stringwill=willChange.getText().toString();
ContentValues values=new ContentValues();
values.put("word", word);
values.put("detail",contents);
int id=resolver.update(uri,values,
"word=?",newString[]{will});//更新内容提供者中的word字段是will的数据
// intid=resolver.update(uri, values, "", null);//更新内容提供者中的uri字段指定的行
Toast.makeText(ShowMessage.this,
"更新的数据条数"+id, Toast.LENGTH_SHORT).show();
}
});
query.setOnClickListener(new View.OnClickListener(){
@Override
public
void onClick(View arg0) {
Cursorcursor=resolver.query(uri, null,
null,null,null);
listWords.clear();
while(cursor.moveToNext()){
listWords.add(cursor.getString(1)+":"+cursor.getString(2));
}
adapter.notifyDataSetChanged();
cursor.close();
}
});
listWords=newArrayList<String>();
adapter=newArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,
listWords);
showWords.setAdapter(adapter);
}
}
ContentProvider是Android的四大组件之一,他可以把自己的数据暴漏出来,让其他应用可以对该数据进行增删改查,若应用程序通过内容提供者暴漏了自己的数据,则无论该应用程序是否启动了,其他应用程序都可通过该接口来操作数据。内容提供者操作的数据可以是数据库数据也可以是文件等他存储方式,如要操作xml文件中user节点下的name节点,通过ContentResolver操作内容提供者,Uri是提供者和操作者之间进行数据交换的标识,通过系统找到对应的ContentProvider,ContentResolver的操作实际是Uri对应的ContentProvider实现的对数据的操作,执行的提供者中的增删改查,ContentResolver执行的insert(),delete(),update(),query()实际是ContentProvider执行的对应的方法,最终执行的都是在内容提供者中。
内容提供者在应用中多以单例模式使用
ContentProvider的使用:
1.内容提供者
(1) 定义类继承ContentProvider基类,重写方法
(2) 在清单文件中注册,注册时需要指定authorities,该属性用于其他应用找到该内容提供者的标记,从而进行操作数据,并设置为可供外部应用调用(exported)
内容提供者的方法:
创建时调用的方法:Oncreate():该方法在内容提供者创建后会被调用,当其他应用第一次访问内容提供者时调用
插入数据时调用的方法 :PublicUri insert(Uri uri,ContentValues values);第一个参数是插入数据的uri地址标记,第二个参数是插入的数据
删除数据时调用的方法:publicint delete(Uri uri,String selection, String[] selectionArgs);//第一个参数是操作的地址,第二个参数是删除的数据的where条件,第三个参数是第二个参数中的条件中的值
更新时调用的方法:public intupdata(Uri uri,ContentValues values,String selection,String[] selectionArgs);//第一个参数是操作的数据的位置,第二参数是根据条件找到的数据修改后的结果,第三个参数是更新数据的条件,第三个参数是更新条件中的?对应的值
查询时调用的方法:publicCursor query(Uri uri,String[] projection,String selection,String[]selectionArgs,String sortOrder);//第一个参数是查询数据的地址,第二个参数是筛选返回的结果,第三个参数是查询的条件不需要则为null,第四个参数是查询条件中的?所指代的数值,第五个参数是查询出的数据的排列方式,是升序或降序。
PublicString getType(Uri uri):该方法用于放回当前Uri所代表的MIME类型,若该Uri对应的数据可能包含多条记录,则MIME类型字符串应该以vnd.android.cursor.dir/开头,若只有一天记录则以vnd.android.cursor.item/开头
2.内容操作者
ContentResolver是用于操作内容提供者提供的数据,在其他应用中通过ContentResolver修改提供的数据。每个方法的返回值的类型就是内容提供者中对应的方法的返回值,执行的也是对应的提供者中的方法。
Context的getContentReslover(),获取ContentReslover对象。
Insert(Uri,ContentValues);//向对应的内容提供者中插入ContentValues的数据。
delete(Uri,String where,String[] selectionArgs);//删除uri对应的内容提供者中的数据,查找条件是where,where中的参数的值是selectionArgs
update(Uri,ContentValues,String where,String[] selectionArgs);//修改uri对应的内容提供者中根据条件找到的数据成ContentValues数据
quert(Uri,String[] projection,String selection,String[]selectionArgs,String sortOrder);查询内容提供者中查询出的数据返回cursor
3.Uri介绍
Uri相当于网络的网址,用于指定操作的位置,Uri分为3部分
以content://org.crazyit.providers.dictproviders/words为例
content://:这是固定的开头,相当于URl中的http://
org.crazyit.providers.dictproviders:这个部分是内容提供者注册中的authorities,通过该部分找到操作的内容提供者,相当于URl中的域名部分
words://:数据部分,相当于URl中的具体文件部分
4.UriMatcher介绍
UriMatcher是用于对uri进行匹配,多使用于在内容提供者中进行增删改查操作时对uri进行匹配,通过匹配进行区分操作,
方法:
addURI(authority,path, code)//第一个参数对内容提供者而言是内容提供者中注册时的authorities属性规定的内容提供者的标记,第二个参数是操作的表名,第三个参数是匹配码,当进行匹配是方法返回的值
match(Uri);进行匹配时调用的方法
5. ContentUri
Uri的工具类,多用于对uri和数据id的添加和解析操作,例如内容提供者中数据操作成功后,返回的uri是插入数据后的添加id后的uri可通过下面的方法进行操作: withAppendedld(uri,id);//将一个id添加到一个uri的末尾形成一个新的uri
parseId(uri);//用于指出一个uri中所包含的id
使用例子:
实体类:
public
classWords {
public
final static String authority="com.myContentProvider";
public
static final
class Word{
public
final static String id="id";
public
final static String word="word";
public
final static String detail="detail";
public
final static Uri urione=Uri.parse("content://com.myContentProvider/words");
public
final static Uri uritwo=Uri.parse("content://com.myContentProvider/word");
}
}
其中一个应用中定义的内容提供者
public
classMyContentProvider extends ContentProvider{
private
staticUriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);//uri匹配器,添加多个Uri则可以匹配多个,其中有匹配码可以用于匹配后返回的值
private
staticfinalintWORES=1;
private
staticfinalintWORD=2;
private
staticfinalintWORDD=4;
private
staticfinalintWORDDS=5;
private Heplpter
heplpter;
//当第一次调用内容提供者时调用,只调用一次
@Override
public
boolean onCreate() {
heplpter=new Heplpter(this.getContext(),
"EnglishDB.db",null,1);//拿到数据库对象就可以对数据库增删改查了
matcher.addURI(Words.authority,
"English",WORES);//用于操作English表,对数据库而言第二个参数是表名,第一个参数是本内容提供者的zuthorities属性,第三个数据是uri的匹配码,当执行增删改查操作的时候,就是通过matcher匹配uri返回的值:相当于content://authorities/表名/id
matcher.addURI(Words.authority,
"English/#",WORD);//用于操作English表的多条数据的匹配//English/#代表的是English表下的某一条数据,使用于列表点击某条查询某条的数据,
matcher.addURI(Words.authority,
"Englishdd",WORDD);//用于操作Englishdd表的多条数据的匹配
matcher.addURI(Words.authority,
"Englishdd/#",WORDD);//用于操作Englishdd表的单条数据的匹配
return
true;
}
//返回uri所代表的数据的mime类型,若uri对应的数据可能包含多条记录,则mime类型字符串应该以vnd.android.cursor.dir/开头,若只包含一条记录,则对应的应该是vnd.android.cursor.item/开头
@Override
public String getType(Uri uri){
//若操作的是集合类型则返回WORDS,若只有一条数据则返回WORD下的数据
switch(matcher.match(uri)){
case
WORES:
return
"vnd.android.cursor.dir./English";//dir是目录的意思,意思是返回English表的集合,这个的返回是根据我们操作的数据返回的结果是一条数据还是一个集合
case
WORD:
return
"vnd.android.cursor.item./English";//item是项的意思,意思是返回English表的某一线,这个的返回是根据我们操作的数据返回的结果是一条数据还是一个集合
case
WORDD:
return
"vnd.android.cursor.dir./Englishdd";//dir是目录的意思,意思是返回Englishdd表的集合,这个的返回是根据我们操作的数据返回的结果是一条数据还是一个集合
case
WORDDS:
return
"vnd.android.cursor.item./Englishdd";//item是项的意思,意思是返回Englishdd表的某一线,这个的返回是根据我们操作的数据返回的结果是一条数据还是一个集合
default:
throw
newIllegalArgumentException("未知Uri:"+uri);
}
}
//根据uri删除selection条件匹配的所有记录
@Override
public
int delete(Uri uri, Stringselection, String[] selectionArgs) {
SQLiteDatabasedb=heplpter.getWritableDatabase();
int num=0;
//uri可能有多个,//下面这个就是对uri进行分类,
switch(matcher.match(uri)){
case
WORES:
num=db.delete("English",selection, selectionArgs);
break;
case
WORD:
long id=ContentUris.parseId(uri);
StringwhereClause=Words.Word.id+"="+id;//id=2的数据
if(selection!=null&&!"".equals(selection)){
whereClause=whereClause+"and"+selection;//拼接条件
}
num=db.delete("English",whereClause, selectionArgs);
break;
default:
throw
newIllegalArgumentException("未知Uri:"+uri);
}
getContext().getContentResolver().notifyChange(uri,null);
db.close();
return num;
}
//根据uri插入对应values数据
@Override
public Uri insert(Uri uri,ContentValues values) {
SQLiteDatabasedb=heplpter.getWritableDatabase();
switch(matcher.match(uri)){
case
WORES:
long rowId=db.insert("English",Words.Word.id,values);//返回值是插入数据的行id
if(rowId>0){
UriwordUri=ContentUris.withAppendedId(uri, rowId);
getContext().getContentResolver().notifyChange(wordUri,null);
db.close();
return wordUri;//插入成功后返回的是插入数据的uri
}
break;
default:
db.close();
throw
newIllegalArgumentException("未知Uri:"+uri);
}
return
null;
}
//根据uri查询出selection条件所匹配的所有记录,,projection是一个列表名,表明只选择出指定的数据列。
@Override
public Cursor query(Uri uri,String[] projection, String selection, String[] sectionArgs,
StringsortOrder) {
SQLiteDatabasedb=heplpter.getWritableDatabase();
Cursorcursor=null;
switch(matcher.match(uri)){
case
WORES:
cursor=db.query("English",projection, selection, sectionArgs,
null, null, sortOrder);
// db.close();
return cursor;
case
WORD:
long id=ContentUris.parseId(uri);
StringwhereClause=Words.Word.id+"="+id;
if(selection!=null&&!"".equals(selection)){
whereClause=whereClause+"and"+selection;
}
cursor=db.query("English",projection, selection, sectionArgs,
null, null, sortOrder);
// db.close();//不能关闭数据库
return cursor;
default:
throw
newIllegalArgumentException("未知Uri:"+uri);
}
}
//根据uri修改selection条件匹配的记录
@Override
public
int update(Uri uri,ContentValues values, String selection, String[] selectionArgds) {
SQLiteDatabasedb=heplpter.getWritableDatabase();
int num=0;
switch(matcher.match(uri)){
case
WORES:
num=db.update("English",values, selection, selectionArgds);
break;
case
WORD:
long id=ContentUris.parseId(uri);
StringwhereClause=Words.Word.id+"="+id;
if(selection!=null&&!"".equals(selection)){
whereClause=whereClause+"and"+selection;
}
num=db.update("English",values, whereClause, selectionArgds);
break;
default:
throw
newIllegalArgumentException("未知Uri:"+uri);
}
getContext().getContentResolver().notifyChange(uri,null);
db.close();
return num;
}
}
SQLiteOpenHelpter:
public class Heplpter extends SQLiteOpenHelper{
//name是创建的数据库的名称后缀是.db,factory是Cursor工厂可以写null为默认的工厂,vertsion是数据库的版本
publicHeplpter(Context context, String name, CursorFactory factory,
intversion) {
super(context,name, factory, version);//使用默认的cursorFactory
}
//当调用getWritableDatabase()(以写的方式打开数据库,若数据库的磁盘空间慢了,数据库则只能读不能写了,此时用本方法打开则会报错)或getReadablDatabase()(先以读写的方式打开数据库,若数据库的磁盘空间慢了,此时打开数据库就会打开失败,则会以只读的方式打开数据库)方法获取数据库对象时调用,若不存在数据库则系统或自动创建爱一个在调用oncreate(),其中自动创建一个表,用于操作数据
@Override
publicvoid onCreate(SQLiteDatabase db) {
db.execSQL("createtable English(id integer primary key autoincrement,word varchar(255),detailvarchar(255))");//执行sql语句
}
//当版本变化时调用,当创建本实例对象时会传入一个version,该version高于之前的版本号则会调用.
@Override
publicvoid onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// publicHeplpter getInstance(){
// returnnew
// }
}
//清单注册:
<provider
android:name="com.example.sharecontent.mycontentprovider.MyContentProvider"
android:authorities="com.myContentProvider"
android:exported="true"
></provider>
//另一个应用的使用ContentResolver
另一个应用布局
<?xml
version="1.0"encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
>
<Button
android:id="@+id/insert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="插入数据"
/>
<Button
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除数据"
/>
<Button
android:id="@+id/update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改数据"
/>
<Button
android:id="@+id/query"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询数据"
/>
<EditText
android:id="@+id/change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="修改数据或查询数据的字段"
/>
<EditText
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="文字描述"
/>
<EditText
android:id="@+id/willChange"
android:layout_width="match_parent"
android:layout_height="40dp"
android:hint="请输入将被修改的词"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical"
>
<ListView
android:id="@+id/showWords"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
</LinearLayout>
另一个应用的类
public
classShowMessage extends Activity{
EditTextchange;
EditTextcontent;
ListViewshowWords;
ArrayAdapteradapter;
List<String>listWords;
EditTextwillChange;
@Override
protected
void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_showmessage);
willChange=(EditText)findViewById(R.id.willChange);
Buttoninsert=(Button) findViewById(R.id.insert);
Buttondelete=(Button) findViewById(R.id.delete);
Buttonupdate=(Button) findViewById(R.id.update);
Buttonquery=(Button) findViewById(R.id.query);
change=(EditText)findViewById(R.id.change);
content=(EditText)findViewById(R.id.content);
showWords=(ListView)findViewById(R.id.showWords);
final ContentResolverresolver=getContentResolver();
final Uri uri=Uri.parse("content://com.myContentProvider/English");//通過uri找到內容提供者
insert.setOnClickListener(new View.OnClickListener(){
@Override
public
void onClick(View arg0) {
Stringword=change.getText().toString();
Stringcontents=content.getText().toString();
ContentValuesvalues=newContentValues();
values.put("word", word);
values.put("detail",contents);
Uriuris=resolver.insert(uri, values);
Toast.makeText(ShowMessage.this,
"添加成功后的uri是"+uris, Toast.LENGTH_SHORT).show();
}
});
delete.setOnClickListener(new View.OnClickListener(){
@Override
public
void onClick(View arg0) {
Stringword=change.getText().toString();
// intid=resolver.delete(uri, "", null);//删除uri指定的数据
int id=resolver.delete(uri,"word=?",newString[]{word});
Toast.makeText(ShowMessage.this,
"删除的是数据"+id, Toast.LENGTH_SHORT).show();
}
});
update.setOnClickListener(new View.OnClickListener(){
@Override
public
void onClick(View arg0) {
Stringword=change.getText().toString();
Stringcontents=content.getText().toString();
Stringwill=willChange.getText().toString();
ContentValues values=new ContentValues();
values.put("word", word);
values.put("detail",contents);
int id=resolver.update(uri,values,
"word=?",newString[]{will});//更新内容提供者中的word字段是will的数据
// intid=resolver.update(uri, values, "", null);//更新内容提供者中的uri字段指定的行
Toast.makeText(ShowMessage.this,
"更新的数据条数"+id, Toast.LENGTH_SHORT).show();
}
});
query.setOnClickListener(new View.OnClickListener(){
@Override
public
void onClick(View arg0) {
Cursorcursor=resolver.query(uri, null,
null,null,null);
listWords.clear();
while(cursor.moveToNext()){
listWords.add(cursor.getString(1)+":"+cursor.getString(2));
}
adapter.notifyDataSetChanged();
cursor.close();
}
});
listWords=newArrayList<String>();
adapter=newArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,
listWords);
showWords.setAdapter(adapter);
}
}
相关文章推荐
- ubuntu16.04安装matplotlibm导致中文乱码的问题解决
- yii框架之简单的验证码实现
- laravel的基础学习(二)
- 日请求亿级的QQ会员AMS平台PHP7升级实践
- php 运行环境搭建
- PHP 工厂模式
- php 设计模式
- PHP与MySQL通讯那点事
- php 单例模式
- PHP多进程(4) :内部多进程
- PHP多进程编程(3):多进程抓取网页的演示
- PHP多进程编程(2):管道通信
- (四)企业部分之lnmp环境的搭建:PHP
- PHP多进程编程(一)
- 如何解决PHP里大量数据循环时内存耗尽的问题
- PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法
- phpstorm git no changes detected
- CI框架源码研读(路由解析)
- 学习phpcms模板方法:
- phpcms:八、show.html