1# Observing Media Assets
2
3The **photoAccessHelper** module provides APIs for listening for media asset (image, video, and album) changes.
4
5> **NOTE**
6>
7> - Before you get started, obtain a **PhotoAccessHelper** instance and apply for required permissions. For details, see [Before You Start](photoAccessHelper-preparation.md).
8> - Unless otherwise specified, the **PhotoAccessHelper** instance obtained in the **Before You Start** section is used to call **photoAccessHelper** APIs. If the code for obtaining the **PhotoAccessHelper** instance is missing, an error will be reported to indicate that **photoAccessHelper** is not defined.
9
10The APIs related to media asset change notifications can be called asynchronously only in callback mode. This topic covers only some of these APIs. For details about all available APIs, see [Album Management](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md).
11
12Unless otherwise specified, all the media assets to be obtained in this document exist in the database. If no media asset is obtained when the sample code is executed, check whether the media assets exist in the database.
13
14## Listening for a URI
15
16Use [registerChange](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#registerchange) to listen for a URI. When the observed object changes, the registered callback will be invoked to return the value.
17
18### Listening for a Media Asset
19
20Register a listener for a **PhotoAsset** instance. When the observed **PhotoAsset** changes, the registered callback will be invoked to return the change.
21
22**Prerequisites**
23
24- A **PhotoAccessHelper** instance is obtained.
25- The application has the ohos.permission.READ_IMAGEVIDEO and ohos.permission.WRITE_IMAGEVIDEO permissions. For details, see [Requesting Permissions](photoAccessHelper-preparation.md#requesting-permissions).
26
27The following example describes how to register a listener for an image and then delete the image. A callback will be invoked when the image is deleted.
28
29**How to Develop**
30
311. [Obtain a media asset](photoAccessHelper-resource-guidelines.md#obtaining-media-assets).
322. Register a listener for the media asset.
333. Delete the media asset.
34
35```ts
36import { dataSharePredicates } from '@kit.ArkData';
37import { photoAccessHelper } from '@kit.MediaLibraryKit';
38const context = getContext(this);
39let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
40
41async function example() {
42  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
43  predicates.equalTo(photoAccessHelper.PhotoKeys.DISPLAY_NAME, 'test.jpg');
44  let fetchOptions: photoAccessHelper.FetchOptions = {
45    fetchColumns: [],
46    predicates: predicates
47  };
48  try {
49    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
50    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
51    console.info('getAssets photoAsset.uri : ' + photoAsset.uri);
52    let onCallback = (changeData: photoAccessHelper.ChangeData) => {
53      console.info('onCallback successfully, changData: ' + JSON.stringify(changeData));
54    }
55    phAccessHelper.registerChange(photoAsset.uri, false, onCallback);
56    await photoAccessHelper.MediaAssetChangeRequest.deleteAssets(context, [photoAsset]);
57    fetchResult.close();
58  } catch (err) {
59    console.error('onCallback failed with err: ' + err);
60  }
61}
62```
63
64### Listening for an Album
65
66Register a listener for an album. When the observed album changes, the registered callback will be invoked to return the change.
67
68**Prerequisites**
69
70- A **PhotoAccessHelper** instance is obtained.
71- The application has the ohos.permission.READ_IMAGEVIDEO and ohos.permission.WRITE_IMAGEVIDEO permissions. For details, see [Requesting Permissions](photoAccessHelper-preparation.md#requesting-permissions).
72
73The following example describes how to register a listener for a user album and then rename the album. A callback will be invoked when the album is renamed.
74
75**How to Develop**
76
771. [Obtain a user album](photoAccessHelper-userAlbum-guidelines.md#obtaining-a-user-album).
782. Register a listener for the user album.
793. Rename the user album.
80
81
82```ts
83import { dataSharePredicates } from '@kit.ArkData';
84import { photoAccessHelper } from '@kit.MediaLibraryKit';
85const context = getContext(this);
86let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
87
88async function example() {
89  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
90  let albumName: photoAccessHelper.AlbumKeys = photoAccessHelper.AlbumKeys.ALBUM_NAME;
91  predicates.equalTo(albumName, 'albumName');
92  let fetchOptions: photoAccessHelper.FetchOptions = {
93    fetchColumns: [],
94    predicates: predicates
95  };
96
97  try {
98    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, fetchOptions);
99    let album: photoAccessHelper.Album = await fetchResult.getFirstObject();
100    console.info('getAlbums successfully, albumUri: ' + album.albumUri);
101
102    let onCallback = (changeData: photoAccessHelper.ChangeData) => {
103      console.info('onCallback successfully, changData: ' + JSON.stringify(changeData));
104    }
105    phAccessHelper.registerChange(album.albumUri, false, onCallback);
106    album.albumName = 'newAlbumName' + Date.now();
107    await album.commitModify();
108    fetchResult.close();
109  } catch (err) {
110    console.error('onCallback failed with err: ' + err);
111  }
112}
113```
114
115## Fuzzy Listening
116
117You can set **forChildUris** to **true** to enable fuzzy listening.<br>If **uri** is an album URI, the value **true** of **forChildUris** enables listening for the changes of the files in the album, and the value **false** enables listening for only the changes of the album itself. <br>If **uri** is the URI of a **photoAsset**, there is no difference between **true** and **false** for **forChildUris**.<br>If **uri** is **DefaultChangeUri**, **forChildUris** must be set to **true**. If **forChildUris** is **false**, the URI cannot be found and no notification can be received.
118
119### Listening for All PhotoAssets
120
121Register a listener for all **PhotoAssets**. When a **PhotoAsset** object changes, the registered callback will be invoked.
122
123**Prerequisites**
124
125- A **PhotoAccessHelper** instance is obtained.
126- The application has the ohos.permission.READ_IMAGEVIDEO and ohos.permission.WRITE_IMAGEVIDEO permissions. For details, see [Requesting Permissions](photoAccessHelper-preparation.md#requesting-permissions).
127
128The following example describes how to register a listener for all media assets and then delete a media asset. A callback will be invoked when the media asset is deleted.
129
130**How to Develop**
131
1321. Register a listener for all media assets.
1332. [Obtain a media asset](photoAccessHelper-resource-guidelines.md#obtaining-media-assets).
1343. Delete the media asset.
135
136```ts
137import { dataSharePredicates } from '@kit.ArkData';
138import { photoAccessHelper } from '@kit.MediaLibraryKit';
139const context = getContext(this);
140let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
141
142async function example() {
143  let onCallback = (changeData: photoAccessHelper.ChangeData) => {
144    console.info('onCallback successfully, changData: ' + JSON.stringify(changeData));
145  }
146  phAccessHelper.registerChange(photoAccessHelper.DefaultChangeUri.DEFAULT_PHOTO_URI, true, onCallback);
147  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
148  let fetchOptions: photoAccessHelper.FetchOptions = {
149    fetchColumns: [],
150    predicates: predicates
151  };
152  try {
153    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
154    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
155    console.info('getAssets photoAsset.uri : ' + photoAsset.uri);
156    await photoAccessHelper.MediaAssetChangeRequest.deleteAssets(context, [photoAsset]);
157    fetchResult.close();
158  } catch (err) {
159    console.error('onCallback failed with err: ' + err);
160  }
161}
162```
163
164## Unregistering Listening for a URI
165
166Use [unRegisterChange](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#unregisterchange) to unregister the listening for the specified URI. Multiple listeners can be registered for a URI. If multiple listener callbacks exist, you can specify a callback to unregister a specific listener. If no callback is specified, all listeners of the URI will be unregistered.
167
168**Prerequisites**
169
170- A **PhotoAccessHelper** instance is obtained.
171- The application has the ohos.permission.READ_IMAGEVIDEO and ohos.permission.WRITE_IMAGEVIDEO permissions. For details, see [Requesting Permissions](photoAccessHelper-preparation.md#requesting-permissions).
172
173The following example describes how to unregister the listening for an image and then delete the image. The unregistered listener callback will not be invoked when the image is deleted.
174
175**How to Develop**
176
1771. [Obtain a media asset](photoAccessHelper-resource-guidelines.md#obtaining-media-assets).
1782. Unregister listening for the URI of the media asset obtained.
1793. Delete the media asset.
180
181```ts
182import { dataSharePredicates } from '@kit.ArkData';
183import { photoAccessHelper } from '@kit.MediaLibraryKit';
184const context = getContext(this);
185let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
186
187async function example() {
188  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
189  predicates.equalTo(photoAccessHelper.PhotoKeys.DISPLAY_NAME, 'test.jpg');
190  let fetchOptions: photoAccessHelper.FetchOptions = {
191    fetchColumns: [],
192    predicates: predicates
193  };
194  try {
195    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
196    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
197    console.info('getAssets photoAsset.uri : ' + photoAsset.uri);
198    let onCallback1 = (changeData: photoAccessHelper.ChangeData) => {
199      console.info('onCallback1, changData: ' + JSON.stringify(changeData));
200    }
201    let onCallback2 = (changeData: photoAccessHelper.ChangeData) => {
202      console.info('onCallback2, changData: ' + JSON.stringify(changeData));
203    }
204    phAccessHelper.registerChange(photoAsset.uri, false, onCallback1);
205    phAccessHelper.registerChange(photoAsset.uri, false, onCallback2);
206    phAccessHelper.unRegisterChange(photoAsset.uri, onCallback1);
207    await photoAccessHelper.MediaAssetChangeRequest.deleteAssets(context, [photoAsset]);
208    fetchResult.close();
209  } catch (err) {
210    console.error('onCallback failed with err: ' + err);
211  }
212}
213```
214