2013-03-25 24 views
5

我已經實現的ContentProviderupdate()和使用getContext().getContentResolver().notifyChange(uri, null);有NotifyChange與改變的URI從contentProvider.update()

我顯然需要通知到觀察者的是,每當只有一個行影響我想與行特定的URI通知,但無法找到辦法。 像"select id where selectionArgs"可以做到這一點,但這將是一個愚蠢的方式。

onchange(boolean, uri)得到完整的uri而不是特定的行,很容易理解,這是因爲ContentProvider.update()發送的是相同的。的MyContentProvider

@Override 
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 

     Log.d("TAG", "update " + uri.getPath()); 

     int count = 0; 
     switch (uriMatcher.match(uri)) { 
     case BOOKS: 
      count = booksDB.update(DATABASE_TABLE, values, selection, selectionArgs); 
      break; 
     case BOOK_ID: 
      count = booksDB.update(DATABASE_TABLE, values, 
        _ID + " = " + uri.getPathSegments().get(1) 
          + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), 
        selectionArgs); 
      break; 
     default: 
      throw new IllegalArgumentException("Unknown URI " + uri); 
     } 

     if (count == 1) { 
      Cursor c = query(uri, new String[] { _ID }, selection, selectionArgs, null); 
      long rowId = Long.valueOf(c.getString(c.getColumnIndex(_ID))); 
      uri = ContentUris.withAppendedId(CONTENT_URI, rowId); 
     } 
     getContext().getContentResolver().notifyChange(uri, null); 
     return count; 

    } 

我會更新表

some code for more clarity 

update()方法的一些怎麼樣的

getContentResolver().update(MyContentProvider.CONTENT_URI, values1, MyContentProvider._ID+"<?", new String[]{"3"})); 

坦率地說,代碼幾乎沒有涉及到問題,只是舉你有些情況下

+0

有些代碼可能是有用的ID。你如何更新許多行? – sandrstar 2013-03-26 08:42:08

+0

確保你對內容提供者的query()方法返回的遊標調用'setNotificationUri(ContentResolver cr,Uri uri)'。更多信息在http://stackoverflow.com/questions/7915050/cursorloader-not-updating-after-data-change。 – 2014-12-20 20:34:57

回答

8

在你的供應商的方法,只返回與ID的URI附加

@Override 
public Uri insert(Uri uri, ContentValues values) { 
    Log.i(TAG, "insert " + uri); 
    final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 
    final int match = URI_MATCHER.match(uri); 

    Uri returnUri; 
    switch (match) { 
     case MESSAGE: { 
      long _id = db.insert(MessageContract.MessageEntry.TABLE_NAME, null, values); 
      if (_id > 0) 
       returnUri = ContentUris.withAppendedId(MessageContract.MessageEntry.CONTENT_URI, _id); 
      else 
       throw new android.database.SQLException("Failed to insert row into " + uri); 
      break; 
     } 

     default: 
      throw new UnsupportedOperationException("Unknown uri: " + uri); 
    } 

    getContext().getContentResolver().notifyChange(returnUri, null); 


    return returnUri; 
} 

而且具有真正的註冊觀察員後代。

getContentResolver().registerContentObserver(MessageContract.MessageEntry.CONTENT_URI, true, mContentObserver); 

爲了從一個開放的,你可以使用ContentUris.parseId(uri)

1

不幸的是我不能建議簡單的解決方案(因爲我不知道完整的代碼和更新您需要運行),我們可以嘗試一些方法(其中一些我已經在我的應用程序中實現):

  • ContentValues提供ID - 這種方式看起來不適用於你的情況,它需要呼叫notifyChange();
  • 爲具有查詢的請求提供特定的Uri(只有一些特定的應用程序需要選擇多個不同的查詢,通常在Uri中包含查詢參數要容易得多)。在程序的另一部分通過該特定的Uri獲得通知後,它將能夠檢查它是否是「當前項目」被更新並且適當地採取行動(例如,最簡單的情況是文章列表和一篇文章在單獨的活動中打開;然後您更新來自服務器的後臺文章您可能還需要更新當前打開的文章,因此需要知道它是否已更新)。您應該能夠使用剛剛收到的Uri來檢查觀察者側面的特定項目,因爲它(Uri)將包含您用於查詢的參數;
+0

>>您應該能夠使用剛收到的Uri來檢查觀察者側面的特定項目,因爲它(Uri)將包含參數<<。我希望它的真實:(在我的情況下,uri就是我發送更新查詢時的內容,並且不涉及自動參數。我想我需要在ContentProvider#update()中手動執行此操作。我的問題是如何做到這一點。 – 2013-03-28 05:33:03

+0

我的意思是,您可以引入特定的Uri,例如BASE/updateItemsWith/dateLater/,而不是使用BASE/updateItemsWith並在更新參數中提供選擇。然後在觀察者中,您將能夠擁有BASE/updateItemsWith/dateLater/並使用它檢查特定項目。 – sandrstar 2013-03-28 05:46:01