欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android ContentProvider的使用实例

程序员文章站 2022-03-25 16:56:51
...

Uri基础

Uri的四个组成部分:content://contacts/people/5

1)schema:已由Android固定设置为content://
2)authority:ContentProvider权限,在AndroidMenifest中设置权限
3)path:要操作的数据库表
4)Id:查询的关键字(可选字段)

Uri的匹配表示要查询的数据,对于单个数据查询,可直接使用Uri定位具体的资源位置,但当范围查询时就需要结合通配符的使用,Uri提供以下两种通配符:

1)*:匹配由任意长度的任何有效字符组成的字符串
2)#:匹配由任意长度的数字字符组成的字符串

ContentProvider使用

ContentProvider一般配合数据库共同使用,实现对外共享数据的目的,所以它需要对数据库的增删改查操作

UriMatcher的作用是在使用Uri操作数据库时,根据发起请求的Uri和配置好的uriMatcher确定本次操作的数据表

ContentObserver,内容观察者,采用观察者模式在存储的数据发生修改时自动触发回调

ContentProvider的使用是通过ContentResolver实例进行操作的,调用getContentResolver()获取ContentResolver实例,进而进行增改删查

权限

android:readPermission:提供程序范围读取权限
android:writePermission:提供程序范围写入权限

 

数据库provider

public class StudentsProvider extends ContentProvider {
    static final String DATABASE_NAME = "College";
    static final String STUDENTS_TABLE_NAME = "students";
    static final int DATABASE_VERSION = 1;

    // 数据库表中的字段
    static final String _ID = "_id";  // 是从1开始计数
    static final String NAME = "name";
    static final String GRADE = "grade";

    private static class DatabaseHelper extends SQLiteOpenHelper {
        public DatabaseHelper(@Nullable Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(" CREATE TABLE " + STUDENTS_TABLE_NAME +
                    " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    " name TEXT NOT NULL, " +
                    " grade TEXT NOT NULL)");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " +  STUDENTS_TABLE_NAME);
            onCreate(db);
        }
    }

    private SQLiteDatabase db;

    static final String PROVIDER_NAME = "com.example.provider.College";
    static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/students");

    static final int STUDENTS = 1;
    static final int STUDENT_ID = 2;

    static final UriMatcher uriMatcher;
    static{
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(PROVIDER_NAME, "students", STUDENTS);
        uriMatcher.addURI(PROVIDER_NAME, "students/#", STUDENT_ID);
    }

    private static HashMap<String, String> STUDENTS_PROJECTION_MAP;

    @Override
    public boolean onCreate() {
        Context context = getContext();
        DatabaseHelper dbHelper = new DatabaseHelper(context);
        db = dbHelper.getWritableDatabase();
        return (db == null)? false:true;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(STUDENTS_TABLE_NAME);

        switch (uriMatcher.match(uri)) {
            case STUDENTS:
                qb.setProjectionMap(STUDENTS_PROJECTION_MAP);
                break;
            case STUDENT_ID:
                qb.appendWhere( _ID + "=" + uri.getPathSegments().get(1));
                break;
        }
        if (sortOrder == null || sortOrder == ""){
            sortOrder = NAME;
        }
        Cursor c = qb.query(db, projection, selection, selectionArgs,null, null, sortOrder);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        long rowID = db.insert(STUDENTS_TABLE_NAME, "", values);  //返回添加后的id
        if (rowID > 0) {
            Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            return _uri;
        }
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)){
            case STUDENTS:
                count = db.delete(STUDENTS_TABLE_NAME, selection, selectionArgs);
                break;
            case STUDENT_ID:
                String id = uri.getPathSegments().get(1);
                count = db.delete( STUDENTS_TABLE_NAME, _ID +  " = " + id +
                        (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
                break;
            default:
                break;
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)){
            case STUDENTS:
                count = db.update(STUDENTS_TABLE_NAME, values, selection, selectionArgs);
                break;
            case STUDENT_ID:
                count = db.update(STUDENTS_TABLE_NAME, values, _ID + " = " + uri.getPathSegments().get(1) +
                        (!TextUtils.isEmpty(selection) ? " AND (" +selection + ')' : ""), selectionArgs);
                break;
            default:
                break;
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
}

权限设置

<provider android:name="StudentsProvider"
	android:authorities="com.example.provider.College" >
</provider>

activity操作数据库

public class MainActivity extends AppCompatActivity {
    // provider uri地址是包括表名
    private Uri studentUri = Uri.parse("content://com.example.provider.College/students");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 注册内容观察者ContentObserver
        getContentResolver().registerContentObserver(studentUri, true, new MyObserver(new Handler()));
    }

    public void onClickAdd(View view) {
        ContentValues values = new ContentValues();
        values.put(StudentsProvider.NAME, ((EditText)findViewById(R.id.tvName)).getText().toString());
        values.put(StudentsProvider.GRADE, ((EditText)findViewById(R.id.tvGrade)).getText().toString());
        Uri uri = getContentResolver().insert(studentUri, values);
        Toast.makeText(getBaseContext(), "onClickAdd", Toast.LENGTH_LONG).show();
    }

    // projection 是要查询的字段,是一个String[]类型,如果为null,则查询所有字段
    // selection 是where子句
    // selectionArgs 是where子句的参数

    public void onClickQuery(View view) {
        Cursor cursor = getContentResolver().query(studentUri, null, null, null, null);
        while (cursor.moveToNext()){
            int stuId = cursor.getInt(0);
            String vName = cursor.getString(cursor.getColumnIndex("name"));
            String vGrade = cursor.getString(cursor.getColumnIndex("grade"));
        }
        cursor.close();
        Toast.makeText(getBaseContext(), "onClickQuery", Toast.LENGTH_LONG).show();
    }

    public void onClickDelete(View view) {
        getContentResolver().delete(studentUri, "name=?", new String[]{"xyz"});
        Toast.makeText(getBaseContext(), "onClickDelete", Toast.LENGTH_LONG).show();
    }

    public void onClickUpdate(View view) {
        Uri uri = ContentUris.withAppendedId(studentUri, 1);
        Log.d("yy", "onClickUpdate, uri = " + uri);
        ContentValues values = new ContentValues();
        values.put(StudentsProvider.NAME, "xyz");
        getContentResolver().update(uri, values, null, null);
        Toast.makeText(getBaseContext(), "onClickUpdate", Toast.LENGTH_LONG).show();

    }

    // 监听数据库的类
    private final class MyObserver extends ContentObserver {
        public MyObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            Log.d("yy", "onChange, uri = " + uri);
            Cursor cursor = getContentResolver().query(studentUri, null, null, null, null);
            while (cursor.moveToNext()){
                int stuId = cursor.getInt(0);
                String vName = cursor.getString(cursor.getColumnIndex("name"));
                String vGrade = cursor.getString(cursor.getColumnIndex("grade"));
                Log.d("yy", "onChange, id = " + stuId + ", name = " + vName + ", grade = " + vGrade);
            }
            cursor.close();
        }
    }
}

<Button
    android:id="@+id/btnUpdate"
    android:text="更新"
    android:onClick="onClickUpdate" />