1# 使用OH_DisplayManager实现屏幕基础信息查询和状态监听 (C/C++)
2
3## 场景介绍
4
5[OH_DisplayManager](../reference/apis-arkui/_o_h___display_manager.md)屏幕管理模块用于提供屏幕的信息查询、屏幕状态变化监听、折叠设备的折叠状态变化监听等能力,应用可根据对应的屏幕信息、屏幕状态变化、屏幕折叠状态适配不同的UI界面显示。
6
7- 支持查询的屏幕信息,包括屏幕的分辨率、物理像素密度、逻辑像素密度、刷新率、屏幕尺寸、屏幕旋转方向、屏幕旋转角度等。
8
9- 支持屏幕状态变化的监听,包括屏幕旋转变化,屏幕分辨率变化、屏幕刷新率变化等。
10
11- 支持查询当前设备是否为可折叠设备,同时支持折叠状态(展开/折叠)变化的监听。
12
13## 基本概念
14
15- 屏幕的物理像素密度(densityDPI):代表每英寸屏幕所拥有的物理像素点数。
16
17- 屏幕的逻辑像素的密度(densityPixels):代表物理像素与逻辑像素的缩放系数比,计算方法为物理像素密度除以160。
18
19## 接口说明
20
21常用接口如下表所示。更多API说明请参考[OH_DisplayManager](../reference/apis-arkui/_o_h___display_manager.md)。
22
23| 接口名 | 描述 |
24| -------- | -------- |
25| OH_NativeDisplayManager_GetDefaultDisplayRotation(NativeDisplayManager_Rotation *displayRotation) | 获取默认屏幕的旋转角度。 |
26| OH_NativeDisplayManager_CreateDefaultDisplayCutoutInfo(NativeDisplayManager_CutoutInfo **cutoutInfo) | 获取挖孔屏、刘海屏、瀑布屏等不可用屏幕区域信息。 |
27| OH_NativeDisplayManager_DestroyDefaultDisplayCutoutInfo(NativeDisplayManager_CutoutInfo *cutoutInfo) |  销毁挖孔屏、刘海屏、瀑布屏等不可用屏幕区域信息。|
28| OH_NativeDisplayManager_IsFoldable()|查询设备是否可折叠。|
29| OH_NativeDisplayManager_RegisterDisplayChangeListener( OH_NativeDisplayManager_DisplayChangeCallback displayChangeCallback, uint32_t *listenerIndex)|注册屏幕状态变化监听(如旋转变化、刷新率、DPI、分辨率等)。|
30|OH_NativeDisplayManager_UnregisterDisplayChangeListener(uint32_t listenerIndex)|取消屏幕状态变化监听。|
31|OH_NativeDisplayManager_RegisterFoldDisplayModeChangeListener( OH_NativeDisplayManager_FoldDisplayModeChangeCallback displayModeChangeCallback, uint32_t *listenerIndex)|注册屏幕展开、折叠状态变化监听。|
32|OH_NativeDisplayManager_UnregisterFoldDisplayModeChangeListener(uint32_t listenerIndex)|取消屏幕展开、折叠状态变化监听。|
33
34## 在CMake脚本中链接动态库
35
36```
37target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
38target_link_libraries(entry PUBLIC libnative_display_manager.so )
39```
40
41## 添加头文件
42
43```c++
44#include <window_manager/oh_display_info.h>
45#include <window_manager/oh_display_manager.h>
46#include <hilog/log.h>
47```
48
49## 获取屏幕状态
50
511. 可以通过OH_NativeDisplayManager_GetDefaultDisplayRotation获取默认屏幕的旋转角度。
52
53   ```c++
54   #include "napi/native_api.h"
55   #include <window_manager/oh_display_info.h>
56   #include <window_manager/oh_display_manager.h>
57   #include <hilog/log.h>
58
59   static napi_value GetDefaultDisplayRotation(napi_env env, napi_callback_info info)
60   {
61       NativeDisplayManager_Rotation displayRotation;
62       NativeDisplayManager_ErrorCode errCode = OH_NativeDisplayManager_GetDefaultDisplayRotation(&displayRotation);
63       if (errCode == NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) {
64           napi_value rotation;
65           napi_create_int32(env, displayRotation, &rotation);
66           return rotation;
67       } else {
68           napi_value errorCode;
69           napi_create_int32(env, errCode, &errorCode);
70           return errorCode;
71       }
72   }
73
74   EXTERN_C_START
75   static napi_value Init(napi_env env, napi_value exports) {
76       napi_property_descriptor desc[] = {
77          {"getDisplayRotation", nullptr, GetDefaultDisplayRotation, nullptr, nullptr, nullptr, napi_default, nullptr},
78       };
79       napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
80       return exports;
81   }
82   EXTERN_C_END
83   ```
84
852. 可以通过OH_NativeDisplayManager_CreateDefaultDisplayCutoutInfo获取挖孔屏、刘海屏、瀑布屏等不可用屏幕区域信息。 可通过OH_NativeDisplayManager_DestroyDefaultDisplayCutoutInfo销毁挖孔屏、刘海屏、瀑布屏等不可用屏幕区域信息。
86
87   ```c++
88   #include "napi/native_api.h"
89   #include <window_manager/oh_display_info.h>
90   #include <window_manager/oh_display_manager.h>
91   #include <hilog/log.h>
92
93   static napi_value CreateDefaultDisplayCutoutInfo(napi_env env, napi_callback_info info)
94   {
95       NativeDisplayManager_CutoutInfo *cutOutInfo = NULL;
96       NativeDisplayManager_ErrorCode errCode = OH_NativeDisplayManager_CreateDefaultDisplayCutoutInfo(&cutOutInfo);
97       OH_LOG_INFO(LOG_APP, "GetDefaultCutoutInfo errCode=%{public}d", errCode);
98       if (errCode == NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) {
99           if (cutOutInfo != NULL && cutOutInfo->boundingRectsLength != 0) {
100               OH_LOG_INFO(LOG_APP, "GetDefaultCutoutInfo cutOutInfo length=%{public}d", cutOutInfo->boundingRectsLength);
101               for (int i = 0; i < cutOutInfo->boundingRectsLength; i++) {
102                   OH_LOG_INFO(LOG_APP, "cutOutInfo[%{public}d]=[%{public}d %{public}d %{public}d %{public}d]",
103                       i, cutOutInfo->boundingRects[i].left, cutOutInfo->boundingRects[i].top,
104                       cutOutInfo->boundingRects[i].width, cutOutInfo->boundingRects[i].height);
105               }
106               OH_LOG_INFO(LOG_APP, "cutOutInfo waterfall left rect=[%{public}d %{public}d %{public}d %{public}d]",
107               cutOutInfo->waterfallDisplayAreaRects.left.left, cutOutInfo->waterfallDisplayAreaRects.left.top,
108               cutOutInfo->waterfallDisplayAreaRects.left.left, cutOutInfo->waterfallDisplayAreaRects.left.left);
109               OH_LOG_INFO(LOG_APP, "cutOutInfo waterfall top rect=[%{public}d %{public}d %{public}d %{public}d]",
110               cutOutInfo->waterfallDisplayAreaRects.top.left, cutOutInfo->waterfallDisplayAreaRects.top.top,
111               cutOutInfo->waterfallDisplayAreaRects.top.left, cutOutInfo->waterfallDisplayAreaRects.top.left);
112               OH_LOG_INFO(LOG_APP, "cutOutInfo waterfall right rect=[%{public}d %{public}d %{public}d %{public}d]",
113               cutOutInfo->waterfallDisplayAreaRects.right.left, cutOutInfo->waterfallDisplayAreaRects.right.top,
114               cutOutInfo->waterfallDisplayAreaRects.right.left, cutOutInfo->waterfallDisplayAreaRects.right.left);
115               OH_LOG_INFO(LOG_APP, "cutOutInfo waterfall bottom rect=[%{public}d %{public}d %{public}d %{public}d]",
116               cutOutInfo->waterfallDisplayAreaRects.bottom.left, cutOutInfo->waterfallDisplayAreaRects.bottom.top,
117               cutOutInfo->waterfallDisplayAreaRects.bottom.left, cutOutInfo->waterfallDisplayAreaRects.bottom.left);
118           }
119           napi_value boundingRectsLength;
120           napi_create_int32(env, cutOutInfo->boundingRectsLength, &boundingRectsLength);
121           OH_NativeDisplayManager_DestroyDefaultDisplayCutoutInfo(cutOutInfo);
122           return boundingRectsLength;
123       } else {
124           napi_value errorCode;
125           napi_create_int32(env, errCode, &errorCode);
126           return errorCode;
127       }
128   }
129
130   EXTERN_C_START
131   static napi_value Init(napi_env env, napi_value exports) {
132       napi_property_descriptor desc[] = {
133           {"getCutoutInfo", nullptr, CreateDefaultDisplayCutoutInfo, nullptr, nullptr, nullptr, napi_default, nullptr},
134       };
135       napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
136       return exports;
137   }
138   EXTERN_C_END
139   ```
140
141
142
143## 监听屏幕状态变化
144
145可以通过OH_NativeDisplayManager_RegisterDisplayChangeListener接口注册屏幕变化的监听,包括屏幕旋转、分辨率变化、刷新率变化、DPI变化等。 通过OH_NativeDisplayManager_UnregisterDisplayChangeListener接口取消屏幕状态变化的监听。
146
147```c++
148#include "napi/native_api.h"
149#include <window_manager/oh_display_info.h>
150#include <window_manager/oh_display_manager.h>
151#include <hilog/log.h>
152
153void DisplayChangeCallback(uint64_t displayId)
154{
155    OH_LOG_INFO(LOG_APP, "DisplayChangeCallback displayId=%{public}lu.", displayId);
156}
157
158static napi_value RegisterDisplayChangeListener(napi_env env, napi_callback_info info)
159{
160    uint32_t listenerIndex;
161    NativeDisplayManager_ErrorCode errCode = OH_NativeDisplayManager_RegisterDisplayChangeListener(
162        DisplayChangeCallback, &listenerIndex);
163    OH_LOG_INFO(LOG_APP, "RegisterDisplayChangeListener listenerIndex =%{public}d errCode=%{public}d.",
164        listenerIndex, errCode);
165    if (errCode == NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) {
166        napi_value registerIndex;
167        napi_create_int32(env, listenerIndex, &registerIndex);
168        return registerIndex;
169    } else {
170        napi_value errorCode;
171        napi_create_int32(env, errCode, &errorCode);
172        return errorCode;
173    }
174}
175
176static napi_value UnregisterDisplayChangeListener(napi_env env, napi_callback_info info)
177{
178    size_t argc = 1;
179    napi_value args[1] = { nullptr };
180
181    uint32_t listenerIndex;
182    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
183    napi_get_value_uint32(env, args[0], &listenerIndex);
184    OH_LOG_INFO(LOG_APP, "UnregisterDisplayChangeListener listenerIndex =%{public}d.", listenerIndex);
185    NativeDisplayManager_ErrorCode errCode = OH_NativeDisplayManager_UnregisterDisplayChangeListener(listenerIndex);
186    OH_LOG_INFO(LOG_APP, "UnregisterDisplayChangeListener errCode=%{public}d.", errCode);
187    napi_value errorCode;
188    napi_create_int32(env, errCode, &errorCode);
189    return errorCode;
190}
191
192EXTERN_C_START
193static napi_value Init(napi_env env, napi_value exports) {
194    napi_property_descriptor desc[] = {
195        {"registerDisplayChange", nullptr, RegisterDisplayChangeListener, nullptr, nullptr, nullptr, napi_default, nullptr},
196        {"unregisterDisplayChange", nullptr, UnregisterDisplayChangeListener, nullptr, nullptr, nullptr,
197            napi_default, nullptr},
198    };
199    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
200    return exports;
201}
202EXTERN_C_END
203
204```
205
206## 监听折叠设备状态变化
207
2081. 可以通过OH_NativeDisplayManager_IsFoldable接口查询设备是不是折叠设备。
209
210   ```c++
211   #include "napi/native_api.h"
212   #include <window_manager/oh_display_info.h>
213   #include <window_manager/oh_display_manager.h>
214   #include <hilog/log.h>
215
216   static napi_value IsFoldable(napi_env env, napi_callback_info info)
217   {
218       bool isFoldDevice = OH_NativeDisplayManager_IsFoldable();
219       OH_LOG_INFO(LOG_APP, "IsFoldable isFoldDevice =%{public}d.", isFoldDevice);
220       napi_value isFold;
221       napi_get_boolean(env, isFoldDevice, &isFold);
222       return isFold;
223   }
224
225   EXTERN_C_START
226   static napi_value Init(napi_env env, napi_value exports) {
227       napi_property_descriptor desc[] = {
228           {"checkIsFoldDevice", nullptr, IsFoldable, nullptr, nullptr, nullptr, napi_default, nullptr},
229       };
230       napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
231       return exports;
232   }
233   EXTERN_C_END
234   ```
2352. 可以通过OH_NativeDisplayManager_RegisterFoldDisplayModeChangeListener注册屏幕展开/折叠状态变化的监听。 通过OH_NativeDisplayManager_UnregisterFoldDisplayModeChangeListener接口取消屏幕展开/折叠状态变化的监听。
236
237   ```c++
238   #include "napi/native_api.h"
239   #include <window_manager/oh_display_info.h>
240   #include <window_manager/oh_display_manager.h>
241   #include <hilog/log.h>
242
243   void FoldDisplayModeChangeCallback(NativeDisplayManager_FoldDisplayMode displayMode)
244   {
245       OH_LOG_INFO(LOG_APP, "displayMode=%{public}d.", displayMode);
246   }
247
248   static napi_value RegisterFoldDisplayModeChangeListener(napi_env env, napi_callback_info info)
249   {
250       uint32_t listenerIndex = 0;
251       NativeDisplayManager_ErrorCode errCode = OH_NativeDisplayManager_RegisterFoldDisplayModeChangeListener(
252           FoldDisplayModeChangeCallback, &listenerIndex);
253       OH_LOG_INFO(LOG_APP, "listenerIndex =%{public}d errCode=%{public}d.",
254           listenerIndex, errCode);
255       if (errCode == NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) {
256           napi_value registerIndex;
257           napi_create_int32(env, listenerIndex, &registerIndex);
258           return registerIndex;
259       } else {
260           napi_value errorCode;
261           napi_create_int32(env, errCode, &errorCode);
262           return errorCode;
263       }
264   }
265
266   static napi_value UnregisterFoldDisplayModeChangeListener(napi_env env, napi_callback_info info)
267   {
268       size_t argc = 1;
269       napi_value args[1] = { nullptr };
270       uint32_t listenerIndex;
271       napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
272       napi_get_value_uint32(env, args[0], &listenerIndex);
273       OH_LOG_INFO(LOG_APP, "listenerIndex =%{public}d.", listenerIndex);
274       NativeDisplayManager_ErrorCode errCode = OH_NativeDisplayManager_UnregisterFoldDisplayModeChangeListener(listenerIndex);
275       OH_LOG_INFO(LOG_APP, "errorCode=%{public}d", errCode);
276       napi_value errorCode;
277       napi_create_int32(env, errCode, &errorCode);
278       return errorCode;
279   }
280
281   EXTERN_C_START
282   static napi_value Init(napi_env env, napi_value exports) {
283       napi_property_descriptor desc[] = {
284       { "registerFoldDisplayModeChange", nullptr, RegisterFoldDisplayModeChangeListener, nullptr, nullptr, nullptr,
285           napi_default, nullptr },
286       { "unregisterFoldDisplayModeChange", nullptr, UnregisterFoldDisplayModeChangeListener, nullptr, nullptr,
287           nullptr, napi_default, nullptr },
288       };
289       napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
290       return exports;
291   }
292   EXTERN_C_END
293   ```