这里写个简单的例子用来存储用户信息。PeopleInfo为用户信息类
package com.wwd.mycontentprovider;
import android.net.Uri;
/**
* Created by wwd on 2016/8/9.
*/
public class PeopleInfo {
//contentprovider的域名
public static final String AUTHORITY = "com.wwd.mycontentprovider.peopleinfo";
public static final String PATH_SINGLE = "people/#";
public static final String PATH_MULTIPLE = "people";
//多项MIME
public static final String MIME_DIR_MULTIPLE = "vnd.android.cursor.dir";
//单项MIME
public static final String MIME_ITEM_SINGLE = "vnd.android.cursor.item";
public static final String TABLE_NAME = "peopleinfo";
//contentprovider的URI
public static final String CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_MULTIPLE;
public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING);
//contentprovider单项的URI
public static final String ALONE_CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_SINGLE;
public static final Uri CONTENT_URI_ALONE = Uri.parse(ALONE_CONTENT_URI_STRING);
public static class People{
public static final String ID = "_id";
public static final String NAME = "name";
public static final String AGE = "age";
}
}
Contentprovider的uri格式如下:
[content://] [com.wwd.mycontentprovider.peopleinfo] [/people] [/#]
|—–A——||————————B—————————–||—-C—-||-D-|
B是AUTHORITY。
C是PATH_MULTIPLE也就是数据类型,如果表中不止保持人物信息,还有其他类型的数据比如货物数据时就需要C来区分了。
D是单项ID,就是每一项item的_id。
我们知道contentprovider的数据列表都是保存在SQL内的,所以先要简单的写一个SQL。具体如下
package com.wwd.mycontentprovider;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by wwd on 2016/8/9.
*/
public class PeopleInfoSQLite extends SQLiteOpenHelper {
private static final String DB_CREATE = "create table "+
PeopleInfo.TABLE_NAME + "("+PeopleInfo.People.ID + " integer primary key autoincrement, "+
PeopleInfo.People.NAME + " text not null, " + PeopleInfo.People.AGE + " integer);";
public PeopleInfoSQLite(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
然后就是主要的contentprovider部分
package com.wwd.mycontentprovider;
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.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
/**
* Created by wwd on 2016/8/9.
*/
public class PeopleProvider extends ContentProvider {
public static final int MULTIPLE_PEOPLE = 1;
public static final int SINGLE_PEOPLE = 2;
public static final UriMatcher uriMatcher;
private static final int SQL_VERSION = 1;
private static final String DB_NAME = "people_db";
private PeopleInfoSQLite peopleSqlite;
//绑定匹配值,uriMatcher.match(uri))返回SINGLE_PEOPLE为单项,MULTIPLE_PEOPLE为多项
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PeopleInfo.AUTHORITY, PeopleInfo.PATH_SINGLE, SINGLE_PEOPLE );
uriMatcher.addURI(PeopleInfo.AUTHORITY, PeopleInfo.PATH_MULTIPLE , MULTIPLE_PEOPLE );
}
@Override
public boolean onCreate() {
peopleSqlite = new PeopleInfoSQLite(getContext(), DB_NAME, null, SQL_VERSION);
SQLiteDatabase database = peopleSqlite.getWritableDatabase();
if(database == null)
return false;
else
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase database = peopleSqlite.getReadableDatabase();
switch(uriMatcher.match(uri)){
case SINGLE_PEOPLE:
long id = ContentUris.parseId(uri);
String where = PeopleInfo.People.ID + "=" + id;
if(selection != null && !"".equals(selection)){
selection = where + "and" + selection;
}
return database.query(PeopleInfo.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
case MULTIPLE_PEOPLE:
return database.query(PeopleInfo.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
}
return null;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)){
case MULTIPLE_PEOPLE:
return PeopleInfo.MIME_DIR_MULTIPLE;
case SINGLE_PEOPLE:
return PeopleInfo.MIME_ITEM_SINGLE;
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase database = peopleSqlite.getWritableDatabase();
long id = database.insert(PeopleInfo.TABLE_NAME, null, values);
Uri newUri = ContentUris.withAppendedId(uri, id);
getContext().getContentResolver().notifyChange(uri, null);
return newUri;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int number = 0;
SQLiteDatabase database = peopleSqlite.getWritableDatabase();
Log.i("wwdlog","delete selection = "+selection);
switch (uriMatcher.match(uri)){
case MULTIPLE_PEOPLE:
number = database.delete(PeopleInfo.TABLE_NAME, selection, selectionArgs);
break;
//根据URI的ID来删除单项数据
case SINGLE_PEOPLE:
String segment = uri.getPathSegments().get(1);
Log.i("wwdlog","segment = " + segment + ", selection = " + selection);
number = database.delete(PeopleInfo.TABLE_NAME, PeopleInfo.People.ID + "=" + segment
+ (!TextUtils.isEmpty(selection) ? " and (" + selection + ')' : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unsupported URI:" + uri);
}
getContext().getContentResolver().notifyChange(uri,null);
return number;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase database = peopleSqlite.getWritableDatabase();
int number = 0;
switch (uriMatcher.match(uri)){
case MULTIPLE_PEOPLE:
number = database.update(PeopleInfo.TABLE_NAME, values, selection, selectionArgs);
break;
case SINGLE_PEOPLE:
String segment = uri.getPathSegments().get(1);
number = database.update(PeopleInfo.TABLE_NAME, values, PeopleInfo.People.ID + "=" + segment, selectionArgs);
break;
}
getContext().getContentResolver().notifyChange(uri, null);
return number;
}
}
这里解释一下query的参数作用,其他相关函数也同理。
public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, String sortOrder)
第一个参数Uri就是PeopleInfo.CONTENT_URI。
第二个参数,projection,这个参数告诉Provider要返回的内容(列Column),如果我们只需要NAME,那么我们可以写成如下格式
Cursor cursor = contentResolver.query(PeopleInfo.CONTENT_URI,new String[]{PeopleInfo.People.NAME}, null, null, null);
第三个参数,selection,设置条件,相当于SQL语句中的where。null表示不进行筛选。比如我们要查找john,可以
String name = john;
getContentResolver().query(PeopleInfo.CONTENT_URI_ALONE, null, PeopleInfo.People.NAME + "='"+name+"'", null, null);
第四个参数,selectionArgs,这个参数是要配合第三个参数使用的,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?具体如下
getContentResolver().query(PeopleInfo.CONTENT_URI_ALONE, null, PeopleInfo.People.NAME + “=?”, new = String[]{name}, null);
第五个参数,sortOrder,按照什么进行排序,相当于SQL语句中的Order by。
这样基本的contentprovider基本写完最后附上activity的调用
package com.wwd.mycontentprovider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button addButton;
private Button delButton;
private Button changeButton;
private Button searchButton;
private TextView showView;
private EditText editName;
private EditText editAge;
private ContentResolver resolver;
private PeopleChangeObserver mObserver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resolver = this.getContentResolver();
addButton = (Button)findViewById(R.id.bt1);
delButton = (Button)findViewById(R.id.bt2);
changeButton = (Button)findViewById(R.id.bt3);
searchButton = (Button)findViewById(R.id.bt4);
editName = (EditText)findViewById(R.id.ed1);
editAge = (EditText)findViewById(R.id.ed2);
showView = (TextView)findViewById(R.id.show_list);
mObserver = new PeopleChangeObserver(null);
initView();
}
class PeopleChangeObserver extends ContentObserver{
public PeopleChangeObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
Log.i("wwdlog","PeopleChangeObserver!! ");
}
}
@Override
protected void onResume() {
getContentResolver().registerContentObserver(PeopleInfo.CONTENT_URI, true, mObserver);
super.onResume();
}
@Override
protected void onPause() {
getContentResolver().unregisterContentObserver(mObserver);
super.onPause();
}
private void initView(){
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put(PeopleInfo.People.NAME, editName.getText().toString());
values.put(PeopleInfo.People.AGE, Integer.parseInt(editAge.getText().toString()));
Uri newUri = resolver.insert(PeopleInfo.CONTENT_URI, values);
Log.i("wwdlog","add success newUri = "+newUri);
}
});
delButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = editName.getText().toString();
String age = editAge.getText().toString();
if (!name.equals("") || !age.equals("")) {
if(!name.equals(""))
getContentResolver().delete(PeopleInfo.CONTENT_URI, PeopleInfo.People.NAME + "='"+name+"'", null);
} else {
Toast.makeText(MainActivity.this, "请输入删除条件",
Toast.LENGTH_LONG).show();
}
}
});
changeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = editName.getText().toString();
String age = editAge.getText().toString();
if(!name.equals("")&&!age.equals("")){
Cursor cursor = getContentResolver().query(PeopleInfo.CONTENT_URI, null, PeopleInfo.People.NAME + "='"+name+"'", null, null);
if(cursor != null){
ContentValues values = new ContentValues();
values.put(PeopleInfo.People.NAME, name);
values.put(PeopleInfo.People.AGE, Integer.parseInt(age));
getContentResolver().update(PeopleInfo.CONTENT_URI, values, PeopleInfo.People.NAME + "=?", new String[]{name});
}
}else {
Toast.makeText(MainActivity.this, "请输入姓名年龄",
Toast.LENGTH_LONG).show();
}
}
});
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
refreshList();
}
});
refreshList();
}
private void refreshList(){
Cursor cursor = getContentResolver().query(PeopleInfo.CONTENT_URI, null, null, null, null);
String table_list = null;
if(cursor != null && cursor.moveToFirst()){
do{
int age = cursor.getInt(cursor.getColumnIndex(PeopleInfo.People.AGE));
String name = cursor.getString(cursor.getColumnIndex(PeopleInfo.People.NAME));
Log.i("wwdlog","init age = "+age+", name = "+name);
table_list += name + " " + age + '\n';
}while(cursor.moveToNext());
}
Log.i("wwdlog", "table_list = "+table_list);
showView.setText(table_list);
}
}
layout如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/bt1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加" />
<Button
android:id="@+id/bt2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除" />
<Button
android:id="@+id/bt3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="更改年龄" />
<Button
android:id="@+id/bt4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询" />
<EditText
android:id="@+id/ed1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入name条件进行增删改查" />
<EditText
android:id="@+id/ed2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输age条件进行增删改查" />
LinearLayout>
<TextView
android:id="@+id/show_list"
android:layout_width="match_parent"
android:layout_height="wrap_content">TextView>
LinearLayout>
AndroidManifest.xml别忘了加上定义
<provider
android:authorities="com.wwd.mycontentprovider.peopleinfo"
android:name=".PeopleProvider" />
application>