2013-03-25 15 views
5

I wprowadziły update() z ContentProvider i powiadomienie obserwatorem getContext().getContentResolver().notifyChange(uri, null);notifyChange ze zmienionych URI z contentProvider.update()

moją oczywistą potrzebę jest to, że gdy tylko jeden wiersz odbywa chcę powiadomić z wiersza określonego URI, ale Nie mogłem znaleźć sposobu, aby to zrobić. dodatkowe zapytanie, takie jak "select id where selectionArgs", może to zrobić, ale będzie to głupi sposób.

Uzyskanie kompletnego adresu uri zamiast określonego wiersza, łatwo zrozumieć, ponieważ dzieje się tak dlatego, że ContentProvider.update() wysyła to samo. Metoda

some code for more clarity 

update() z 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; 

    } 

będę aktualizować tabela jakiś sposób jak

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

szczerze mówiąc, kod ledwo podobne do pytania, po prostu staramy się dać Wasz kontekst

+0

jakiś kod może być przydatne. Jak zaktualizować wiele wierszy? – sandrstar

+0

Upewnij się, że wywołałeś 'setNotificationUri (ContentResolver cr, Uri uri)' na kursorze zwróconym przez metodę 'query()' dostawcy treści. Więcej informacji na http://stackoverflow.com/questions/7915050/cursorloader-not-updating-after-data-change. –

Odpowiedz

8

W swojej metodzie dostawcy, tylko zwrócić URI z identyfikatora dołączany

@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; 
} 

i zarejestrować obserwatora z prawdą dla potomków.

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

Aby uzyskać identyfikator z Uri można użyć ContentUris.parseId(uri)

1

Niestety, nie jestem nie jest w stanie zasugerować łatwego rozwiązania (ponieważ nie mam pojęcia o pełnym kodzie i aktualizacjach, które musisz uruchomić), jest kilka sposobów, które możemy wypróbować (niektóre z nich zaimplementowałem w aplikacjach kopalnianych):

  • Podaj identyfikatory w kodzie ContentValues - w ten sposób wygląda na nieprzydatną dla Twojego przypadku i wymaga pętli z połączeniami do notifyChange();
  • Podaj konkretne Uri dla zapytań z zapytaniami (tylko niektóre aplikacje wymagają wielu różnych zapytań w doborze, zwykle znacznie łatwiej jest uwzględnić parametr zapytania w Uri). Po otrzymaniu powiadomienia od innej części programu z tym konkretnym Uri, będzie mógł sprawdzić, czy "aktualny produkt" został zaktualizowany i działać właściwie (np. Najprostszy przypadek z listą artykułów i jednym artykułem otwartym w oddzielnej działalności, a następnie Aktualizujesz listę artykuły w tle z serwera Może być konieczne zaktualizowanie aktualnie otwartego artykułu również i tak, trzeba wiedzieć, czy został zaktualizowany). Powinieneś być w stanie sprawdzić konkretny element po stronie obserwatora, używając właśnie odebranego Uri, ponieważ on (Uri) będzie zawierał parametry, których użyłeś do zapytania;
+0

>> Powinieneś być w stanie sprawdzić konkretny element po stronie obserwatora, używając właśnie odebranego Uri, ponieważ on (Uri) będzie zawierał parametr (y) <<. Życzyłbym sobie, aby było prawdziwe :(w moim przypadku uri jest po prostu tym, co wysyłam w zapytaniu o aktualizację i nie angażuję automatycznie parametrów.Poprawdę trzeba to zrobić ręcznie w ContentProvider # update().i moje pytanie dotyczy tego, jak to zrobić. –

+0

Mam na myśli, możesz wprowadzić konkretne Uri jak BASE/updateItemsWith/dateLater/ zamiast używać BASE/updateItemsWith i udostępniając wybór w argumentach aktualizacji. Następnie w obserwatorze Będziesz mógł mieć BASE/updateItemsWith/dateLater/ i sprawdzić konkretny przedmiot za jego pomocą. – sandrstar

Powiązane problemy