ContentObserver получает уведомления об удалениях, но не вставках или обновлениях

#android #contentobserver

#Android #contentobserver

Вопрос:

У меня есть следующий код в моей деятельности:

 Cursor mCursor = managedQuery(ActivityColumns.CONTENT_URI, PROJECTION, null, null,
                getSortOrderStringFromSpinner());

        mCursor.registerContentObserver(new ContentObserver(new Handler())
        {
            @Override
            public void onChange(boolean selfChange)
            {
                ...snip...// breakpoint is set here                 
            }

            @Override
            public boolean deliverSelfNotifications()
            {
                return true;
            }
        });
  

… и в dataProvider, который я использую для получения своих данных, я устанавливаю URI уведомления в методе запроса на uri типа, для которого я запрашиваю:

 c.setNotificationUri(getContext().getContentResolver(), uri);
  

Наконец, при обновлении, вставке и удалении, если операция выполнена успешно, подписчики уведомляются:

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

notificationUri в строке выше — это URI вставляемого / обновляемого или удаленного элемента.

С точкой останова, установленной в строке кода «… snip …», я добавляю, удаляю и обновляю некоторые записи. Я получаю уведомления только об удалениях, но не об обновлениях или вставках. Что я делаю не так?

Ответ №1:

Проблема была именно такой, как я и подозревал: наблюдатель контента не получал обновлений о вставках или обновлениях, потому что действие со списком, который должен был обновляться, было приостановлено на время. Чтобы вставить или обновить запись в моем приложении, пользователь запускает другое действие, где он редактирует запись, и нажимает «Отправить».

Затем сохранение выполняется в

 protected void onActivityResult (int requestCode, int resultCode, Intent data) 
  

О чем я не знал, и я узнал, когда прочитал документацию, так это о том, что onActivityResult является:

Вызывается при завершении запущенного вами действия, предоставляя вам код запроса, с которым вы его запустили, возвращенный код результата и любые дополнительные данные из него. Результирующий код будет RESULT_CANCELED, если действие явно вернуло это, не вернуло никакого результата или произошло сбой во время его выполнения.

Вы получите этот вызов непосредственно перед onResume (), когда ваша активность возобновится.

Итак, суть в том, что действие не было активным, когда я выполнял вставки и обновления, и, следовательно, оно не получало уведомлений о вставках или обновлениях.

Удаления бывают разными, потому что мое приложение удаляет элементы из списка, когда в контекстном меню выбрано «Удалить». Действие остается активным все время.

Ответ №2:

Это все еще требует дополнительного тестирования, но, похоже, проблема заключалась в том, что активность с content observer, которая не получала уведомления, была приостановлена, когда произошло обновление курсора. И приостановленная активность не получает событий… Я думаю…

Ответ №3:

Вызов

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

Должна содержать ссылку на то, что наблюдатель за контентом был уведомлен, т. е

 getContext().getContentResolver().notifyChange(notificationUri, MyContentObserver);