博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android笔记(五十六) Android四大组件之一——ContentProvider,实现自己的ContentProvider...
阅读量:5020 次
发布时间:2019-06-12

本文共 10894 字,大约阅读时间需要 36 分钟。

      有时候我们自己的程序也需要向外接提供数据,那么就需要我们自己实现ContentProvider。

      自己实现ContentProvider的话需要新建一个类去继承ContentProvider,然后重写类中的的6个抽象方法。

      onCreate():初始化内容提供器时候会调用,通常会在这里完成对数据库的创建和升级等操作,返回true表示内容提供器初始化成功,返回false则表示失败,注意,只有当存在ContentResolver尝试访问我们程序中的数据时,内容提供其才会被初始化

      query():从内容提供其中查询数据,使用uri参数来确定查询哪张表,projection参数用于确定查询哪些列,selection和selectionArgs参数用于约束查询哪些行,sortOrder参数用于对结果进行排序,查询结果存放在Cursor对象中返回。

      insert():向内容提供器中添加一条数据,使用uri参数来确定要添加到的表,待添加的数据保存在values参数中,添加完成后,返回一个用于表示这条新记录的URI。

      update():更新内容提供器中已有的数据,使用uri参数来确定更新哪一张表中的数据,新数据保存在values参数中,selection和selectionArgs参数用于约束更新哪些列,受影响的行数将作为返回值返回。

      delete():从内容提供其中删除数据,使用uri参数来确定删除哪一张表中的数据,selection和selectionArgs参数用于约束删除哪些行,被删除的行数将作为返回值返回。

      getType():根据传入的内容URI来返回相应的MIME类型。

      可以看到,几乎每一个方法都会带有Uri这个参数,这个参数也正是调用ContentResolver的增删改查方法时传递过来的,而现在,我们需要对传入的Uri参数进行解析,从中分析出调用方期待访问的表和数据。

      一般的标准的内容URI写法是这样的

      content://com.example.app.provider/table1

      这就表示调用方期待访问的是com.example.app这个应用的table1表中的数据。除此之外,我们还可以在这个内容URI的后面加上一个id,例如

      content://com.example.app.provider/table1/1

      这就表示调用方期待访问的是com.example.app这个应用的table1表中的id为1的数据。

      内容URI的格式主要就只有以上两种,以路径结尾就表示期望访问该表中所有的数据,以id结尾就表示期望访问该表中拥有相应的id的数据,我们可以使用通配符的方式来分别匹配这两种格式的内容URI,规则如下

      1.*表示匹配任意长度的任意字符

      2.#表示匹配任意长度的数据

      所以一个能够匹配任意表的内容URI格式就可以写成:

      content://com.example.app.provider/*

      而一个能够匹配table1表中任意一行数据的内容URI格式就可以写成

      content://com.example.app.provider/table1/#

      接着我们再借助UriMatcher这个类就可以轻松的实现匹配内容URI的功能,UriMatcher中提供了一个addURI()方法,这个方法接收三个参数,可以分别把权限,路径和一个自定义代码传递进去,这样,当调用UriMatcher的match()方法时,就可以将一个Uri对象传入,返回值是某个能够匹配这个Uri对象所对应的自定义代码,利用这个代码,我们就可以判断出调用方期待访问的是哪张表中的数据了。

      除此之外,还有一个getTypt()方法,它是所有的内容提供其都必须提供的一个方法,用于获取Uri对象所对应的MIME类型,一个内容URI所对应的MIME字符串主要由三部分组成,Android对这三个部分做了如下格式规定:

      1.必须以vnd开头

      2.如果内容URI以路径结尾,则后面接android.cursor.dir/,如果内容URI以id结尾,则后接android.cursor.item/。

      3.最后接上vnd.<authority>.<path>

      简单示例:

MyContentProvider

MyContentProvider.java

package cn.lixyz.mycontentprovider;import android.content.ContentProvider;import android.content.ContentValues;import android.content.Context;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;import android.net.Uri;public class MyContentProvider extends ContentProvider {    public static final int STUDENTS_DIR = 0;    public static final int STUDENTS_ITEM = 1;    public static final int CLASSES_DIR = 2;    public static final int CLASSES_ITEM = 3;    private static UriMatcher uriMatcher;    private MyDBHelper myDBHelper;    private SQLiteDatabase database;    private static final String AUTHORITY = "cn.lixyz.mycontentprovider.cp";    static {        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);        uriMatcher.addURI("cn.lixyz.mycontentprovider.cp", "students", STUDENTS_DIR);        uriMatcher.addURI("cn.lixyz.mycontentprovider.cp", "students/#", STUDENTS_ITEM);        uriMatcher.addURI("cn.lixyz.mycontentprovider.cp", "classes", CLASSES_DIR);        uriMatcher.addURI("cn.lixyz.mycontentprovider.cp", "classes/#", CLASSES_ITEM);    }    @Override    public boolean onCreate() {        myDBHelper = new MyDBHelper(getContext(), "school.db", null, 1);        return true;    }    @Override    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {        database = myDBHelper.getReadableDatabase();        Cursor cursor = null;        switch (uriMatcher.match(uri)) {        case STUDENTS_DIR:            cursor = database.query("students", projection, selection, selectionArgs, null, null, sortOrder);            break;        case STUDENTS_ITEM:            String studentID = uri.getPathSegments().get(1);            cursor = database.query("students", projection, "_id=?", new String[] { studentID }, null, null, sortOrder);            break;        case CLASSES_DIR:            cursor = database.query("classes", projection, selection, selectionArgs, null, null, sortOrder);            break;        case CLASSES_ITEM:            String classID = uri.getPathSegments().get(1);            cursor = database.query("classes", projection, "_id=?", new String[] { classID }, null, null, sortOrder);            break;        }        return cursor;    }    @Override    public String getType(Uri uri) {        switch (uriMatcher.match(uri)) {        case STUDENTS_DIR:            return "vnd.android.cursor.dir/vnd.cn.lixyz.mycontentprovider.cp.students";        case STUDENTS_ITEM:            return "vnd.android.cursor.item/vnd.cn.lixyz.mycontentprovider.cp.students";        case CLASSES_DIR:            return "vnd.android.cursor.dir/vnd.cn.lixyz.mycontentprovider.cp.classes";        case CLASSES_ITEM:            return "vnd.android.cursor.item/vnd.cn.lixyz.mycontentprovider.cp.classes";        }        return null;    }    @Override    public Uri insert(Uri uri, ContentValues values) {        database = myDBHelper.getWritableDatabase();        Uri returnUri = null;        switch (uriMatcher.match(uri)) {        case STUDENTS_DIR:        case STUDENTS_ITEM:            long newStudent = database.insert("students", null, values);            returnUri = Uri.parse("content://" + AUTHORITY + "/students/" + newStudent);            break;        case CLASSES_DIR:        case CLASSES_ITEM:            long newClass = database.insert("classes", null, values);            returnUri = Uri.parse("content://" + AUTHORITY + "/classes/" + newClass);            break;        }        return returnUri;    }    @Override    public int delete(Uri uri, String selection, String[] selectionArgs) {        // TODO Auto-generated method stub        return 0;    }    @Override    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {        // TODO Auto-generated method stub        return 0;    }    class MyDBHelper extends SQLiteOpenHelper {        private Context mContext;        public MyDBHelper(Context context, String name, CursorFactory factory, int version) {            super(context, name, factory, version);            this.mContext = context;        }        @Override        public void onCreate(SQLiteDatabase db) {            db.execSQL(                    "create table if not exists students (_id integer primary key autoincrement,studentName text,studentAge integer,class text)");            db.execSQL("create table if not exists classes (_id integer primary key autoincrement,className text)");        }        @Override        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {            // TODO Auto-generated method stub        }    }}

 

AndroidManifest.xml

MyContentResolver

MainActivity.java

package cn.lixyz.mycontentresolver;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    public void clickButton(View view) {        switch (view.getId()) {        case R.id.bt_addclass:            addClass();            break;        case R.id.bt_addstudent:            addStudent();            break;        case R.id.searchclass:            searchClass();            break;        case R.id.searchstudent:            searchStrudent();            break;        }    }    // 搜索学生方法    private void searchStrudent() {        Uri uri = Uri.parse("content://cn.lixyz.mycontentprovider.cp/students");        ContentResolver contentResolver = getContentResolver();        Cursor cursor = contentResolver.query(uri, null, null, null, null);        if (cursor != null) {            cursor.moveToFirst();            while (cursor.moveToNext()) {                String tudentName = cursor.getString(cursor.getColumnIndex("studentName"));                int studentAge = cursor.getInt(cursor.getColumnIndex("studentAge"));                String className = cursor.getString(cursor.getColumnIndex("class"));                Log.d("TTTT", "学生姓名:" + tudentName + ",年龄 : " + studentAge + ",所在班级:" + className);            }        }    }    // 搜索班级方法    private void searchClass() {        Uri uri = Uri.parse("content://cn.lixyz.mycontentprovider.cp/classes");        ContentResolver contentResolver = getContentResolver();        Cursor cursor = contentResolver.query(uri, null, null, null, null);        if (cursor != null) {            cursor.moveToFirst();            while (cursor.moveToNext()) {                String className = cursor.getString(cursor.getColumnIndex("className"));                Log.d("TTTT", "班级:" + className);            }        }    }    // 添加学生方法    private void addStudent() {        String studentName = et_studentname.getText().toString().trim();        String studentAge = et_studentage.getText().toString().trim();        String studentClass = et_studentclass.getText().toString().trim();        Uri uri = Uri.parse("content://cn.lixyz.mycontentprovider.cp/students");        ContentResolver contentResolver = getContentResolver();        ContentValues cv = new ContentValues();        cv.put("studentName", studentName);        cv.put("studentAge", studentAge);        cv.put("class", studentClass);        Uri returnUri = contentResolver.insert(uri, cv);        Log.d("TTTT", "returnUri:" + returnUri.toString());    }    // 添加班级方法    private void addClass() {        ContentResolver contentResolver = getContentResolver();        Uri uri = Uri.parse("content://cn.lixyz.mycontentprovider.cp/classes");        String className = et_addclass.getText().toString().trim();        ContentValues cv = new ContentValues();        cv.put("className", className);        contentResolver.insert(uri, cv);    }    private EditText et_addclass, et_studentname, et_studentage, et_studentclass;    private Button bt_addclass, bt_addstudent, searchclass, searchstudent;    private void initView() {        et_addclass = (EditText) findViewById(R.id.et_addclass);        et_studentname = (EditText) findViewById(R.id.et_studentname);        et_studentage = (EditText) findViewById(R.id.et_studentage);        et_studentclass = (EditText) findViewById(R.id.et_studentclass);        bt_addclass = (Button) findViewById(R.id.bt_addclass);        bt_addstudent = (Button) findViewById(R.id.bt_addstudent);        searchclass = (Button) findViewById(R.id.searchclass);        searchstudent = (Button) findViewById(R.id.searchstudent);    }}

 

activity_main.xml

 

  这样,就可以在ContentResolver应用中,对ContentProvider应用的数据库进行insert和query操作了。

转载于:https://www.cnblogs.com/xs104/p/4957798.html

你可能感兴趣的文章
基于Gram_schmidt的GDCV
查看>>
Android简洁漂亮的引导页
查看>>
sql如何取每组中的前N个
查看>>
rubymine debug需要安装依赖
查看>>
zbb20170802 cmd 常用命令
查看>>
mysql之group_concat函数详解
查看>>
Sql中EXISTS与IN的使用及效率
查看>>
加快C++编译速度四个方法
查看>>
字典树模板【经测试,几个函数都好用】
查看>>
2017.11.3 微机原理与接口技术----第六章 存储器
查看>>
【OSG】运行OSG示例出现的奶牛不完整问题
查看>>
Highcharts 柱状图为series 动态赋值
查看>>
Javascript 数据类型
查看>>
HDU2732 Leapin' Lizards 网络流 最大流 SAP
查看>>
MyEclipse 更改自带的Tomcate配置
查看>>
使用JS调用腾讯接口获取天气
查看>>
设计模式——备忘录模式
查看>>
由验证码和session丢失的引发原因
查看>>
MYBatis 动态SQL
查看>>
WebApi 学习随笔(一)
查看>>