有一说一,内容提供者这四大组件基本算是最没牌面的四大组件之一了。做了好几年的开发只听说过这个玩意,还从来没有用过这玩意。
最近项目中需要用到这个组件,需求是子应用的数据存入到数据库(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);
以上就完成了内容提供者跨应用读取数据的需求。