1e41f4b71Sopenharmony_ci# Managing External Storage Devices (for System Applications Only)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciBecause external storage devices are pluggable, OpenHarmony provides functions for listening for the device insertion/removal events and mounting/unmounting an external storage device.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciExternal storage devices are managed by the StorageManager and StorageDaemon services. StorageDaemon implements underlying listening and mount/unmount functions. StorageManager provides status change notifications and query and management of external storage devices for system applications.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci**Figure 1** External storage device management 
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci![External storage device management](figures/external-storage-device-management.png)
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci- When an external storage device is inserted, the StorageDaemon process obtains an insertion event over netlink and creates a disk device and volume. The created volume is in the **UNMOUNTED** state.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci- Then, the StorageDaemon process checks the volume. The volume transits to the **CHECKING** state.
14e41f4b71Sopenharmony_ci  - If the check is successful, the StorageDaemon process mounts the volume. If the mount operation is successful, the volume state changes to **MOUNTED** and StorageManager is instructed to send the COMMON_EVENT_VOLUME_MOUNTED broadcast.
15e41f4b71Sopenharmony_ci  - If the check fails, the volume state changes to **UNMOUNTED**.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci- For a volume in the **MOUNTED** state:
18e41f4b71Sopenharmony_ci  - If the user chooses **Eject device**, the volume state changes to **EJECTING** and COMMON_EVENT_VOLUME_EJECT is broadcast. After StorageDaemon unmounts the volume, the volume state changes to **UNMOUNTED** and COMMON_EVENT_VOLUME_UNMOUNTED is broadcast.
19e41f4b71Sopenharmony_ci    <br>For a volume in the **UNMOUNTED** state, removing the device will delete the volume information and broadcast COMMON_EVENT_VOLUME_REMOVED.
20e41f4b71Sopenharmony_ci  - If the user removes the device, the volume state changes to **EJECTING** and then to **UNMOUNTED**, and the broadcasts of the corresponding states are sent. After the device is removed, the volume information is deleted and the COMMON_EVENT_VOLUME_BAD_REMOVAL broadcast is sent.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci## Available APIs
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ciFor details about APIs related to external storage device management, see [Volume Management](../reference/apis-core-file-kit/js-apis-file-volumemanager-sys.md).
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ciThe following table describes the broadcast related parameters.
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci**Table 1** Broadcast parameters
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci| Broadcast| Parameter| 
31e41f4b71Sopenharmony_ci| -------- | -------- |
32e41f4b71Sopenharmony_ci| usual.event.data.VOLUME_REMOVED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.| 
33e41f4b71Sopenharmony_ci| usual.event.data.VOLUME_UNMOUNTED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.| 
34e41f4b71Sopenharmony_ci| usual.event.data.VOLUME_MOUNTED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.<br>**fsUuid**: universally unique identifier (UUID) of the volume.<br>**path**: path where the volume is mounted.| 
35e41f4b71Sopenharmony_ci| usual.event.data.VOLUME_BAD_REMOVAL | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.| 
36e41f4b71Sopenharmony_ci| usual.event.data.VOLUME_EJECT | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.| 
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci## How to Develop
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ciYou can subscribe to broadcast events to observe the insertion and removal of external storage devices, and query or manage volumes based on the volume information obtained from the broadcast.
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci1. Apply for permissions.<br>
43e41f4b71Sopenharmony_ci   Apply for the ohos.permission.STORAGE_MANAGER permission if your application needs to subscribe to volume broadcast events. For details, see [Requesting Permissions for system_basic Applications](../security/AccessToken/determine-application-mode.md#requesting-permissions-for-system_basic-applications).
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci2. Subscribe to broadcast events.<br>
46e41f4b71Sopenharmony_ci   You can subscribe to the following events:
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci   - "usual.event.data.VOLUME_REMOVED": The device is removed.
49e41f4b71Sopenharmony_ci   - "usual.event.data.VOLUME_UNMOUNTED": The volume is unmounted.
50e41f4b71Sopenharmony_ci   - "usual.event.data.VOLUME_MOUNTED": The volume is mounted.
51e41f4b71Sopenharmony_ci   - "usual.event.data.VOLUME_BAD_REMOVAL": The device is forcibly removed.
52e41f4b71Sopenharmony_ci   - "usual.event.data.VOLUME_EJECT": The device is being ejected.
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci   ```ts
55e41f4b71Sopenharmony_ci   import { commonEventManager } from '@kit.BasicServicesKit';
56e41f4b71Sopenharmony_ci   import { volumeManager } from '@kit.CoreFileKit';
57e41f4b71Sopenharmony_ci   import { BusinessError } from '@kit.BasicServicesKit';
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci   let subscriber: commonEventManager.CommonEventSubscriber;
60e41f4b71Sopenharmony_ci   async function example() {
61e41f4b71Sopenharmony_ci     const subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
62e41f4b71Sopenharmony_ci       events: [
63e41f4b71Sopenharmony_ci         "usual.event.data.VOLUME_REMOVED",
64e41f4b71Sopenharmony_ci         "usual.event.data.VOLUME_UNMOUNTED",
65e41f4b71Sopenharmony_ci         "usual.event.data.VOLUME_MOUNTED",
66e41f4b71Sopenharmony_ci         "usual.event.data.VOLUME_BAD_REMOVAL",
67e41f4b71Sopenharmony_ci         "usual.event.data.VOLUME_EJECT"
68e41f4b71Sopenharmony_ci       ]
69e41f4b71Sopenharmony_ci     };
70e41f4b71Sopenharmony_ci     subscriber = await commonEventManager.createSubscriber(subscribeInfo);
71e41f4b71Sopenharmony_ci   }
72e41f4b71Sopenharmony_ci   ```
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci3. Obtain volume information from the broadcast.
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci   ```ts
77e41f4b71Sopenharmony_ci   commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => {
78e41f4b71Sopenharmony_ci     if (data.event === 'usual.event.data.VOLUME_MOUNTED') {
79e41f4b71Sopenharmony_ci       // Manage the volume device based on the information obtained from the broadcast.
80e41f4b71Sopenharmony_ci       let volId: string = data.parameters.id;
81e41f4b71Sopenharmony_ci       volumeManager.getVolumeById(volId, (error: BusinessError, vol: volumeManager.Volume) => {
82e41f4b71Sopenharmony_ci         if (error) {
83e41f4b71Sopenharmony_ci           console.error('volumeManager getVolumeById failed for ' + JSON.stringify(error));
84e41f4b71Sopenharmony_ci         } else {
85e41f4b71Sopenharmony_ci           console.info('volumeManager getVolumeById successfully, the volume state is ' + vol.state);
86e41f4b71Sopenharmony_ci         }
87e41f4b71Sopenharmony_ci       })
88e41f4b71Sopenharmony_ci     }
89e41f4b71Sopenharmony_ci   })
90e41f4b71Sopenharmony_ci   ```
91