内容提供者(ContentProvider)的使用

有一说一,内容提供者这四大组件基本算是最没牌面的四大组件之一了。做了好几年的开发只听说过这个玩意,还从来没有用过这玩意。
最近项目中需要用到这个组件,需求是子应用的数据存入到数据库(SQLite)中,然后主Launcher应用需要读取修改删除子应用的数据库中的数据,然后就用到了这个ContentProvider。

分析需求实现步骤:
1.子应用中创建SQLite数据库,建好表。
2.子应用中创建好ContentProvider,并且定义好匹配的Uri。
3.ContentProvider中重写对应方法,例如主Launcher只需要查,删,的方法的话子应用的内容提供者中只需要重写query()和delete()方法。
4.主Luancher中调用getContentResolver()获取ContentResolver对象调用对应的方法 传入对应的Uri就行了。

代码:
1.创建数据库:

public class EvaluatDbHelper extends SQLiteOpenHelper {
//创建数据库语句
    private String createTab = "create table evaluat (text text,type text,url text)";

    public EvaluatDbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    //建表
        db.execSQL(createTab);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

2.创建内容提供者:

public class EvaluatContentProvider extends ContentProvider {
    private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    private EvaluatDbHelper dbHelper;

    @Override
    public boolean onCreate() {
    	//添加删除和查询的匹配规则
        uriMatcher.addURI("com.lee.lee.EvaluatContentProvider", "delete", 0);
        uriMatcher.addURI("com.lee.lee.EvaluatContentProvider", "query", 1);
        dbHelper = new EvaluatDbHelper(getContext(), "evaluat", null, 1);
        return false;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
    	//重写查询的方法
        if (uriMatcher.match(uri) == 1) {
            SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
            return writableDatabase.query("evaluat", projection, selection, selectionArgs, null, null, null);
        }
        return null;
    }

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

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
    //重写删除的方法
        int evaluat = 0;
        if (uriMatcher.match(uri) == 0) {
            SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
            evaluat = writableDatabase.delete("evaluat", selection, selectionArgs);
        }
        return evaluat;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }
}

既然是组件的话肯定是需要在清单文件中去注册的,这个别忘了,

<provider
            android:authorities="com.lee.lee.EvaluatContentProvider"
            android:name=".EvaluatContentProvider"
            android:exported="true"/>

这里需要注意android:authorities属性中的com.lee.lee.EvaluatContentProvider需要和uriMatcher.addURI(“com.lee.lee.EvaluatContentProvider”, “delete”, 0);中的第一个参数一致 不然是接受不到的。

3.主程序中调用查询和删除的方法。

//这个就是子程序中的定义的Uri  固定格式是content://XXXXXX/需要执行的
public static final Uri  TABLE_EV_query=Uri.parse("content://com.lee.lee.EvaluatContentProvider/query");
//查询子程序的数据库
Cursor cursor = contentResolver.query(TABLE_EV_query, null, null, null, null, null);
这样就获取到了游标
while (cursor.moveToNext()) {
                    StudyRequestBean studyRequestBean = new StudyRequestBean();
                    studyRequestBean.content = cursor.getString(0);
                    studyRequestBean.contentType = cursor.getString(1);
                    studyRequestBean.recording = cursor.getString(2);
                }
                cursor.close();
                这样就把数据库中读取的数据存入至一个StudyRequestBean 类中。
//删除子应用数据库的方法。我这里是全部删除,也可以删除某一项。
 contentResolver.delete(TABLE_EV_delete, null, null);

以上就完成了内容提供者跨应用读取数据的需求。

上一篇:D. Not Quite Lee(Codeforces Global Round 17)


下一篇:在MacOs上配置Hadoop和Spark环境