Android中自定义ContentProvider及用法

时间:2021-04-28 22:42:32
一。自定义ContentProvier时,需要继承ContentProvider,并实现其中的6个方法:
onCreate():一般完成数据库的创建,当指定数据库不存在时,则创建一个数据库,当已经存在时,则不再执行该方法,即该方法之执行一次;
insert():插入数据;
query():查询数据;
delete():删除数据;
update():修改数据;
getType():会根据传入的URI值返回相应的MIME类型,格式如下:
1.如果Uri以路径结尾,则返回值为:return vnd.android.cursor.dir/vnd.+权限+路径;
2.如果Uri以id结尾,则返回值为:return vnd.andnroid.cursor.item/vnd.+权限+路径;

二。借助URIMatcher类,实现对传入Uri值得匹配,核心代码如下:
   static{
//得到UriMatcher实例
uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(authority, "student", TABLE_DIR);
uriMatcher.addURI(authority, "student/#", TABLE_ITEM);
}

三。自定义ContentProvider需要在清单文件中注册:必须有name和authority,如:
   <provider android:name="com.example.testcustomcontentprovider.MyContentProvider"
            android:authorities="com.example.testsqlitehelper"> 
        </provider>
四。具体实例:
(一)创建数据库
/**
 * 继承SQLiteOpenHelper,并重写之方法,构造函数
 *
 */
public class MyOpenHelper extends SQLiteOpenHelper {


//建表语句:id为主键,自增 ;name 文本类型,age 整形,sex 文本类型
private final String CREATE_STUDENT="create table student(" +
"id integer primary key autoincrement," +
"name text," +
"age integer," +
"sex text," +
"job text)";
public MyOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);

}


/**
* 当dbHelper.getWritableDatabase(),时若存在数据库,则不再执行onCreate(),若不存在则执行onCreate();
* 同时完成对表的创建
*/
@Override
public void onCreate(SQLiteDatabase db) {
// 执行建表语句
db.execSQL(CREATE_STUDENT);
}


/**
* 对数据库的升级
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(newVersion>oldVersion){
db.execSQL("drop table id exists student");
onCreate(db);
}
}
}


(二)自定义ContentProvider
public class MyContentProvider extends ContentProvider {


//声明UriMatcher对象
private static UriMatcher uriMatcher;
//声明并初始化权限
private static String authority="com.example.testsqlitehelper";
//初始化匹配码
private static final int TABLE_DIR=1;
private static final int TABLE_ITEM=2;
//声明数据库
private MyOpenHelper dbHelper;
private SQLiteDatabase db;
static{
/**
* 得到UriMatcher实例,当URIMatcher调用match()方法时,会进行匹配,并返回相应的自定义匹配码,根据匹配码进行操作

*/
uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
//添加Uri,参数:1.权限,2.路径,3.自定义的匹配码
uriMatcher.addURI(authority, "student", TABLE_DIR);
uriMatcher.addURI(authority, "student/#", TABLE_ITEM);

}
/**
* 创建或者打开数据库,只执行一次。当指定数据库名的数据库不存在时,创建新的数据库,当存在时,打开已有数据库
*/
@Override
public boolean onCreate() {
dbHelper=new MyOpenHelper(getContext(), "Person.db", null, 1);
return true;
}


@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//创建或者打开数据库
db=dbHelper.getWritableDatabase();
Cursor cursor=null;
switch(uriMatcher.match(uri)){
case TABLE_DIR:

cursor=db.query("student", projection, selection, selectionArgs, null, null, sortOrder);
break;
case TABLE_ITEM:
//将Uri字符串权限之后的部分用“/”进行分割,截取到List集合中,并找到通过索引找到id
String studentID=uri.getPathSegments().get(1);

cursor=db.query("student", projection, "id=?", new String[]{studentID}, null, null, sortOrder);
break;

}
return cursor;
}


@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case TABLE_DIR:
return "vnd.android.cursor.dir/vnd."+authority+".student";
case TABLE_ITEM:
return "vnd.android.cursor.item/vnd."+authority+".student";

default:
break;
}
return null;
}


@Override
public Uri insert(Uri uri, ContentValues values) {
Uri newUri=null;
db=dbHelper.getWritableDatabase();
switch(uriMatcher.match(uri)){
case TABLE_DIR:
case TABLE_ITEM:
long newID=db.insert("student", null, values);
newUri=Uri.parse("content://"+authority+"/student/"+newID);

break;
}
return newUri;
}


@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
db=dbHelper.getWritableDatabase();
int id=0;
switch(uriMatcher.match(uri)){
case TABLE_DIR:
id=db.delete("student", null, null);
break;
case TABLE_ITEM:
String studentId=uri.getPathSegments().get(1);
id=db.delete("student", "id=?", new String[]{studentId});
break;

}
return id;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
db=dbHelper.getWritableDatabase();
int id=0;
switch(uriMatcher.match(uri)){
case TABLE_DIR:
id=db.update("student", values, null, null);
break;
case TABLE_ITEM:
String studentId=uri.getPathSegments().get(1);
id=db.update("student", values, "id=?", new String[]{studentId});
break;

}
return id;
}
}
(三)在清单文件中注册:
<provider android:name="com.example.testcustomcontentprovider.MyContentProvider"
            android:authorities="com.example.testsqlitehelper">
        </provider>

(四)在MainActivity中进行CRUD操作:
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
   
    /**
     * 添加数据
     */
    public void insertData(View view){
    ContentValues values=new ContentValues();
    values.put("name", "张三");
    values.put("age", 21);
    values.put("sex", "男");
    values.put("job", "学生");
    getContentResolver().insert(Uri.parse("content://com.example.testsqlitehelper/student"), values);
    Toast.makeText(MainActivity.this, "添加数据成功", Toast.LENGTH_SHORT).show();

    }

运行结果:

Android中自定义ContentProvider及用法


    /**
     * 查询数据
     */
    public void queryData(View view){
    Cursor cursor=null;
    Uri uri=Uri.parse("content://com.example.testsqlitehelper/student");
    cursor=getContentResolver().query(uri, null, null, null, null);
    while(cursor.moveToNext()){
    String name=cursor.getString(cursor.getColumnIndex("name"));
    String age=cursor.getString(cursor.getColumnIndex("age"));
    String sex=cursor.getString(cursor.getColumnIndex("sex"));
    String job=cursor.getString(cursor.getColumnIndex("job"));
    Log.i("TAG", name+","+age+","+sex+","+job);

    }

    }

运行结果:

Android中自定义ContentProvider及用法

    /**
     * 修改数据
     * @param view
     */
    public void updateData(View view){
    //修改数据库中第二条数据
    Uri uri=Uri.parse("content://com.example.testsqlitehelper/student/2");

    ContentValues values=new ContentValues();
    values.put("age", 40);
    getContentResolver().update(uri, values, null, null);
    Toast.makeText(MainActivity.this, "修改成功", Toast.LENGTH_SHORT).show();

    }

运行结果:

Android中自定义ContentProvider及用法

    /**
     * 删除数据
     */
    public void deleteData(View view){
    //删除第二行的数据
    Uri url=Uri.parse("content://com.example.testsqlitehelper/student/2");
    getContentResolver().delete(url, null, null);

    Toast.makeText(MainActivity.this, "删除成功", Toast.LENGTH_SHORT).show();
    }

}

运行结果:

Android中自定义ContentProvider及用法