我已经设置了一个片段,使用CursorLoader从自定义内容提供程序中提取数据。
问题在于,当我使用内容解析器更新SQLite表中的记录时,光标不会刷新,即getContext().getContentResolver().notifyChange(myUri, null)
无效。我必须退出片段并再次打开它以查看更改。
我认为问题是加载程序没有观察到我用来更新行的URI:
content://com.myapp.provider/MyTable/Set/22
content://com.myapp.provider/MyTable/167
167标识表中的唯一行。 22表示表中的一组行。 有没有办法告诉加载器行167进入集合22,所以应该重置光标?
以下是代码,以便更清晰:
在片段中创建CursorLoader:
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle queryBundle) {
CursorLoader cursorLoader = new CursorLoader(getActivity(), Uri.parse("content://com.myapp.provider/MyTable/Set/22"), myProjection, null, null, null);
return cursorLoader;
}
点击片段中的按钮:
mContext.getContentResolver().update("content://com.myapp.provider/MyTable/167", values, null, null);
内容提供商类:
private static final String AUTHORITY = "com.myapp.provider";
private static final String TABLE_PATH = "MyTable";
public static final String CONTENT_URI_BASEPATH = "content://" + AUTHORITY + "/" + TABLE_PATH;
private static final int URITYPE_TABLE = 1;
private static final int URITYPE_SINGLE_SET = 2;
private static final int URITYPE_SINGLE_ROW = 3;
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static{
sUriMatcher.addURI(AUTHORITY, TABLE_PATH,URITYPE_TABLE);
sUriMatcher.addURI(AUTHORITY, TABLE_PATH + "/Set/#", URITYPE_SINGLE_SET);
sUriMatcher.addURI(AUTHORITY, TABLE_PATH + "/#", URITYPE_SINGLE_ROW);
}
@Override
public int update(Uri myUri, ContentValues values, String selection, String[] selectionArgs){
int rowCount = 0;
String id;
SQLiteDatabase db = localDB.getWritableDatabase();
int uriType = sUriMatcher.match(myUri);
switch(uriType){
case URITYPE_SINGLE_ROW :
id = uri.getLastPathSegment();
//selection and selectionArgs are ignored since the URI itself identifies a unique row.
rowCount = db.update(MyTable.TABLE_NAME, values, MyTable.COLUMN_ID + " = ?", new String[] {id});
}
getContext().getContentResolver().notifyChange(myUri, null);
return rowCount;
}
答案 0 :(得分:5)
我遇到了类似的问题并找到了solution here。
简而言之,事实证明我需要在我的内容提供商的setNotificationUri(ContentResolver cr, Uri uri)
方法返回的游标上调用query()
。
答案 1 :(得分:4)
解决方法是在正在观察的Uri上调用notifyChange()
,即集合而不是行。
为实现这一目标,我们需要做出一些改变:
调用更新时在URI中包含集ID:
mContext.getContentResolver().update("content://com.myapp.provider/MyTable/Set/22/167", values, null, null);
从&#34; /#&#34;更改单行的URI模式到&#34; /设置/#/#&#34;
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static{
sUriMatcher.addURI(AUTHORITY, TABLE_PATH,URITYPE_TABLE);
sUriMatcher.addURI(AUTHORITY, TABLE_PATH + "/Set/#", URITYPE_SINGLE_SET);
sUriMatcher.addURI(AUTHORITY, TABLE_PATH + "/Set/#/#", URITYPE_SINGLE_ROW);
}
然后在更新函数中,构造一个必须通知的新Uri:
List<String> pathSegments = uri.getPathSegments();
String mySetID = pathSegments.get(2);
Uri mySetUri = Uri.parse("content://" + AUTHORITY + "/" + TABLE_PATH + "/Set/" + mySetID);
getContext().getContentResolver().notifyChange(mySetUri, null);