背景
メディアモニタリングは非常に一般的な機能です。たとえば、携帯電話に付属のギャラリーは、撮影された写真の生成を監視するとギャラリーを自動的に更新し、最新のデータをタイムリーにユーザーに表示するために使用されます。 , チャット ページでは、フォト アルバムを監視し、新しい写真がある場合は、撮影した写真などを送信するかどうかをユーザーに尋ねる小さなポップアップ ウィンドウが表示されます。
!!!コードは記事の最後にあります!!!!
この記事では、生成された写真とビデオを監視する方法を説明します。
環境
win10
4.0+
jdk 1.8
アイデア
実際、監視を実装するコードは、クエリの比較とシステム メソッドの呼び出しという同じ種類のコードが行き来するだけですが、この記事では監視に ContentResolver を使用します。
成し遂げる
まず、イメージの生成を監視するには、ContentReslver の registerContentObserver メソッドを通じてそれを監視し、最後に onChange() メソッドをコールバックします。
コアコードは次のとおりです。
getBaseContext().getContentResolver().registerContentObserver(
MediaStore.Images.Media.INTERNAL_CONTENT_URI,
true, this);
getBaseContext().getContentResolver().registerContentObserver(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
true, this);
ご覧のとおり、URL は内部と外部を区別していますが、実際の意味は本体ストレージと外部ストレージを監視することであり、互換性の観点からは両方を記述する必要があります。
ソースコードを見ると、次のようになります。
/**
* Register an observer class that gets callbacks when data identified by a
* given content URI changes.
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#O}, all content
* notifications must be backed by a valid {@link ContentProvider}.
*
* @param uri The URI to watch for changes. This can be a specific row URI,
* or a base URI for a whole class of content.
* @param notifyForDescendants When false, the observer will be notified
* whenever a change occurs to the exact URI specified by
* <code>uri</code> or to one of the URI's ancestors in the path
* hierarchy. When true, the observer will also be notified
* whenever a change occurs to the URI's descendants in the path
* hierarchy.
* @param observer The object that receives callbacks when changes occur.
* @see #unregisterContentObserver
*/
public final void registerContentObserver(@NonNull Uri uri,
boolean notifyForDescendants,
@NonNull ContentObserver observer) {
Objects.requireNonNull(uri, "uri");
Objects.requireNonNull(observer, "observer");
registerContentObserver(
ContentProvider.getUriWithoutUserId(uri),
notifyForDescendants,
observer,
ContentProvider.getUserIdFromUri(uri, mContext.getUserId()));
}
ブール値パラメータのnotifyForDescendantsについては、trueに設定するとメディアタイプに関連する変更の監視がコールバックされることがわかり、広く普及しており関連性の高い設定であることがわかります。false に設定すると、このクラスのみが指定されたものとみなされます 指定されたディレクトリとして認識できます 相関性は低くなります 一部のモデルではこのパラメータが原因で失敗する可能性があります
同様に、ビデオ監視の場合、コアコードは次のとおりです。
getBaseContext().getContentResolver().registerContentObserver(
MediaStore.Video.Media.INTERNAL_CONTENT_URI, true, this);
getBaseContext().getContentResolver().registerContentObserver(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, this);
同様に、違いは Uri 設定が異なることです。
知らせ
(1) 登録がある場合は解放を行う必要があり、そうしないとメモリ リークが発生することに注意してください。メモリ リークについて書かないのは Android 開発者の基本的な資質であり、メモリ リークを修正する方法を知ることが、資格のある Android 開発者の基準となります。
(2) 登録時に、ハンドラーはコールバック中のスレッドのタイプに関連する受信スレッドをカスタマイズできます。コールバックのソースコードは次のとおりです。
/** @hide */
public final void dispatchChange(boolean selfChange, @NonNull Collection<Uri> uris,
@NotifyFlags int flags, @UserIdInt int userId) {
if (mHandler == null) {
onChange(selfChange, uris, flags, userId);
} else {
mHandler.post(() -> {
onChange(selfChange, uris, flags, userId);
});
}
}
コールバック中に、null ではないハンドラーを渡すと、そのハンドラーが呼び出されることがわかります。
(3) コールバック遅延はシステムのソース コード レベルに属し、カスタマイズされたルームでない場合は変更できません。ここで私が提案できるのは、一部のシステムでの遅延を避けるために、渡すハンドラーを使用しないことだけです。一部のシステムでは、渡すハンドラーに遅延操作が含まれるためです。
コードアドレス
CtxObserverManager クラスを検索
それだけです - - - - - - - - - - - - - - - - - - - - - - - - ----------------------------