3

일부 배경 정보를 작동하지 않습니다위해 ContentResolver.notifyChange()

내 응용 프로그램, 전경 활동 내 로컬 SQLite 데이터베이스에서 정보를 캐시를 표시하고 그 사이에 백그라운드 서비스가 서버에 연결하고 신선한 정보를 가져옵니다를 실행 . 데이터가 검색되면 서비스가 내 ContentProvider의 insert 메소드를 실행하여 로컬 SQLite 데이터베이스를 업데이트합니다. 삽입이 완료되면 내용을 변경하기 위해 ContentObserver (포어 그라운드 활동)에 변경 사항을 알립니다.

응용 프로그램을 수동으로 다시 실행하면 화면에 새 데이터가 표시 될 수 있기 때문에 삽입이 제대로 작동한다는 것을 알고 있습니다. 불행히도 자동 새로 고침이 작동하지 않습니다. ContentObserver.notifyChange() 메서드 호출은 실패합니다. 가장 이상한 것은 그것이 심지어 catch (Exception e) 라인에서 멈추지 않는다는 것입니다. 그것은 바로 try/catch 블록 바깥쪽으로갑니다. 나는 무슨 일이 벌어지고 있는지 전혀 모른다. LogCat 및 console은 조용합니다.

다음은 삽입 및 변경 알림을 담당하는 내 ContentProvider 내의 insert 코드의 일부입니다.

SQLiteDatabase sqlDB = db.getWritableDatabase(); 
try { 
    long newID = sqlDB.insertOrThrow(StatsCollectorDatabase.TABLE_USERS, null, values); 
    if (newID > 0) { 
     Uri newUri = ContentUris.withAppendedId(uri, newID); 
     ContentResolver contentResolver = getContext().getContentResolver(); 
     contentResolver.notifyChange(uri, null); // This is the line that fails 
     return newUri; 
    } else { 
     throw new SQLException("Failed to insert row into " + uri); 
    } 
} catch (SQLiteConstraintException e) { 
    Log.i(DEBUG_TAG, "Ignoring constraint failure."); 
} catch (Exception e) { 
    Log.i(DEBUG_TAG, e.getLocalizedMessage()); 
} 

여기 전경 활동에 onCreate 방법의 코드입니다 :

Cursor cursor = this.managedQuery(StatsCollectorProvider.CONTENT_URI, null, null, null, null); 
String[] columns = new String[] { StatsCollectorDatabase._USER_NAME, StatsCollectorDatabase._USER_DEVICE_ID }; 
int[] views = new int[] { R.id.name_entry, R.id.number_entry }; 

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this.getApplicationContext(), R.layout.list_item, cursor, columns, views, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); 
this.setListAdapter(adapter); 

Intent intent = new Intent(this.getApplicationContext(), UsersDownloaderService.class); 
this.startService(intent);  

제가 인터넷 검색을 시도했지만 관련된 아무것도 찾을 수 없습니다. 이 문제를 어떻게 수정합니까?

필요한 경우 더 많은 코드를 제공 할 수 있습니다.

+1

'managedQuery'와'notifyChange'에 동일한 기본 URL을 사용하고 있습니까? 플래그없이'SimpleCursorAdapter'를 인스턴스화하는 유사한 코드를 가지고 있습니다. 아마 마지막 인자를 생략 해 볼 수 있습니다 ... – ge0rg

+0

힌트를 보내 주셔서 감사합니다. 비록, 당신에게 upvote, 친절한 선생님, 내 문제에 참여하는 유일한 사람이었습니다;) – Moyshe

답변

2

해결했습니다. 내 액티비티는 FragmentActivity를 상속하지 않았으며 레이아웃에 조각이 포함되어 있지 않아 작동하지 않았습니다. 등록 된 ContentObservers가 없습니다.

는 이제 다음과 같습니다

주요 활동이 조각 레이아웃을 등록하고 onCreate 방법의에서 백그라운드 서비스를 시작 벗고 첫째 : 이것은 내 list 레이아웃

super.onCreate(savedInstanceState); 
setContentView(R.layout.list); 

Intent intent = new Intent(this.getApplicationContext(), UsersDownloaderService.class); 
this.startService(intent); 

입니다 :

<?xml version="1.0" encoding="utf-8"?> 
<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
    class="org.moyshe.cursors.ListViewFragment" 
    android:name="org.moyshe.cursors.ListViewFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 
</fragment> 

클래스 ListViewFragmentListFragment을 확장하고을 구현합니다.. 이것은 내가 놓친 ContentObserver입니다. 누군가가 어떻게 보이는지에 관심이 있으시면 article을 읽어보십시오. 그것이 나에게 많은 도움이되었습니다.

내 서비스 및 ContentProvider 클래스는 변경되지 않았습니다.

1

나는 유사한 문제가있어서 solution here을 발견했습니다.

간단히 말해서 내 콘텐츠 공급자의 query() 메서드에서 반환 한 커서에 setNotificationUri(ContentResolver cr, Uri uri)을 호출해야했습니다.