ContentObserver の onChange() メソッドが何度も呼び出される
-
21-12-2019 - |
質問
デバイス上で作成された .jpg タイプの新しい画像ファイルを追跡する必要があります。私はこれを使用してこれを行いました ContentObserver
の上 MediaStore
以下のクラスを使用して MediaStoreObserver
そして、私のサービスの1つに同じものを登録します。
私はそれに気づきました onChange()
メソッドは 1 つのファイル作成のために何度も呼び出されます。作成されたメディア ファイルが多くのテーブルで更新されることを理解しています。 MediaStore
したがって onChange()
何度も呼ばれる。
私の質問:登録方法 MediaStore
画像ファイルの作成/編集操作のみ?
- アドバンス、マンジュ
private class MediaStoreObserver extends ContentObserver {
public MediaStoreObserver() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//check image file changes in MediaStore
readFromMediaStore(_context,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
}
//register for external media changes for image files
if(mediaStoreObserver!=null){
_context.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
false,mediaStoreObserver);
解決
短い答え: できません、送信するのはプロバイダーです notifyChange
(オブザーバーとともに受け取りました) onChange
) 何かがあるときはいつでも:更新/挿入/削除
より長い答え: これは、あなたが望むことを達成するために何をしたかです(画像ファイルの作成/編集操作のみのために MediaStore に登録するにはどうすればよいですか?):
開始時に MediaStore から画像テーブルを読み取り、_data 列 (ファイル パス) を並べ替えて保存します。 collection
, 、並べ替え collection
パス(文字列)を使用します。そして、あなたが受け取るたびに、 onChange
上記の並べ替えの新しいコレクションを呼び出し、新しいコレクションをループして、作成した元のコレクションを二分探索で検索します (コレクションは並べ替えられており、時間の複雑さを低く抑えたいため)。これにより、実行時間 O(n*logn) の非常に効率的な実装が可能になります。
または、疑似コードで次のようにします。
1. Read current image columns from media store (the `_data column as projection)
2. Store result in a collection, with string type
3. Sort collection
4. Upon `onChange` is received, make a new collection as step 1-3
5. Loop over collection created in 4 and search each string you take out with
binary search in the sorted collection you got from step 3, if item is not found
then the item is new
6. Make the collection in 4 the current cached version of mediastore
7. Time complexity is O(n*log n) for the above algorithm
編集 更新されたファイル部分については、ステップ 5 の検索がヒットするたびに、MediaStore から変更日フィールドを読み取ります。つまり、実際には次のようにする必要があります。 ファイル (uri) と変更日の両方を保存する データ クラス内ですが、検索ルックアップとしてファイル パスを使用します。ファイルが見つかった場合は、変更日が一致するかどうかを確認する必要があります。一致しない場合は、そのファイルは更新されたファイルです。
他のヒント
私はこの問題を有し、私のsuper.onchange
オーバーライドからonchange
を削除することによってそれを修正しました。