查看: 345|回复: 0

鸿蒙ASCF屏幕控制API实践:亮度调节常亮与截屏监听

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在鸿蒙元服务开发中,屏幕相关能力往往直接影响用户体验。比如视频播放时需要保持亮屏、阅读场景需要调节亮度、金融类服务需要防止截屏泄露信息。ASCF(Ability Service Collaboration Framework)针对这些场景提供了6个屏幕API,覆盖亮度控制、常亮设置、截屏监听和防截屏,接口形式简洁,上手成本很低。本文基于实际开发经验,梳理这些API的用法、典型场景以及容易踩的坑。

一、亮度控制:设置与获取

亮度控制有两个接口:setScreenBrightness用于设置亮度,getScreenBrightness用于获取当前亮度。设置时value的取值范围是0到1,0最暗,1最亮。如果传入-1,则恢复为跟随系统亮度。
  1. // 设置亮度为50%
  2. has.setScreenBrightness({
  3.   value: 0.5,
  4.   success: () => {
  5.     console.info('亮度设置成功');
  6.   },
  7.   fail: (err) => {
  8.     console.error('亮度设置失败:', err);
  9.   }
  10. });
  11. // 恢复系统亮度
  12. has.setScreenBrightness({
  13.   value: -1,
  14.   success: () => {
  15.     console.info('已恢复系统亮度');
  16.   }
  17. });
复制代码

获取当前亮度时,如果返回值是-1,说明当前亮度跟随系统,而不是一个具体的数值。代码里需要对这个特殊值做判断,避免直接用0-1的逻辑处理。
  1. has.getScreenBrightness({
  2.   success: (res) => {
  3.     console.info('当前亮度:', res.value);
  4.     // value 范围 0-1,-1 表示跟随系统
  5.   },
  6.   fail: (err) => {
  7.     console.error('获取亮度失败:', err);
  8.   }
  9. });
复制代码

一个典型场景是阅读模式。进入阅读模式时,先保存当前亮度,再把亮度调到0.3;退出时恢复之前保存的亮度。实现逻辑如下:
  1. Page({
  2.   data: {
  3.     isReadingMode: false,
  4.     originalBrightness: -1,
  5.   },
  6.   toggleReadingMode() {
  7.     let that = this;
  8.     if (that.data.isReadingMode) {
  9.       // 退出阅读模式,恢复亮度
  10.       has.setScreenBrightness({
  11.         value: -1,
  12.         success: () => {
  13.           that.setData({ isReadingMode: false });
  14.           has.showToast({ title: '已退出阅读模式' });
  15.         }
  16.       });
  17.     } else {
  18.       // 先保存当前亮度
  19.       has.getScreenBrightness({
  20.         success: (res) => {
  21.           that.setData({ originalBrightness: res.value });
  22.           // 设置低亮度
  23.           has.setScreenBrightness({
  24.             value: 0.3,
  25.             success: () => {
  26.               that.setData({ isReadingMode: true });
  27.               has.showToast({ title: '已进入阅读模式' });
  28.             }
  29.           });
  30.         }
  31.       });
  32.     }
  33.   }
  34. });
复制代码

注意:setScreenBrightness设置的亮度只在当前元服务内生效,切到其他应用或回到桌面后会自动恢复系统亮度,无法全局改变系统亮度。如果需要全局调节,应使用系统能力@ohos.brightness。

二、屏幕常亮:setKeepScreenOn

setKeepScreenOn用于控制屏幕是否保持常亮。参数keepScreenOn为true时开启,false时关闭。接口本身很简单,但要注意生命周期管理。
  1. // 开启常亮
  2. has.setKeepScreenOn({
  3.   keepScreenOn: true,
  4.   success: () => {
  5.     console.info('屏幕常亮已开启');
  6.   },
  7.   fail: (err) => {
  8.     console.error('设置失败:', err);
  9.   }
  10. });
  11. // 关闭常亮
  12. has.setKeepScreenOn({
  13.   keepScreenOn: false,
  14.   success: () => {
  15.     console.info('屏幕常亮已关闭');
  16.   }
  17. });
复制代码

最典型的场景是视频播放。播放时开启常亮,暂停时关闭,页面销毁时也要记得关闭,避免异常退出导致亮屏状态残留。
  1. Page({
  2.   data: {
  3.     isPlaying: false,
  4.   },
  5.   onVideoPlay() {
  6.     this.setData({ isPlaying: true });
  7.     has.setKeepScreenOn({ keepScreenOn: true });
  8.   },
  9.   onVideoPause() {
  10.     this.setData({ isPlaying: false });
  11.     has.setKeepScreenOn({ keepScreenOn: false });
  12.   },
  13.   onUnload() {
  14.     // 页面销毁时关闭常亮
  15.     has.setKeepScreenOn({ keepScreenOn: false });
  16.   }
  17. });
复制代码

导航场景也常用常亮。导航页面在onShow时开启常亮,onHide时关闭,保证用户在不触碰屏幕时也能持续看到路线。
  1. Page({
  2.   onShow() {
  3.     // 导航页面开启常亮
  4.     has.setKeepScreenOn({
  5.       keepScreenOn: true,
  6.       success: () => {
  7.         console.info('导航模式:屏幕常亮');
  8.       }
  9.     });
  10.   },
  11.   onHide() {
  12.     // 页面隐藏时关闭常亮
  13.     has.setKeepScreenOn({ keepScreenOn: false });
  14.   }
  15. });
复制代码

和亮度设置一样,常亮设置也是临时的,只在当前元服务内有效。用户退出元服务后,屏幕会恢复正常熄屏策略,这是系统保护机制,不是Bug。

三、截屏监听:onUserCaptureScreen

ASCF提供onUserCaptureScreen来监听用户截屏行为,offUserCaptureScreen用于移除监听。注册回调后,只要用户触发系统截屏,回调就会执行。
  1. // 注册截屏监听
  2. const onCapture = function() {
  3.   console.info('用户截屏了');
  4.   // 可以在这里做安全提示
  5. };
  6. has.onUserCaptureScreen(onCapture);
  7. // 移除监听
  8. has.offUserCaptureScreen(onCapture);
复制代码

需要注意,onUserCaptureScreen只能注册一个监听函数。如果重复注册,后面的回调会覆盖之前的,所以建议在页面级别统一管理,避免多个模块互相干扰。

实际场景中,截屏监听常用于安全提示。比如金融类页面或私密聊天页面,用户截屏后立即弹出一条警示,提示“截屏已记录”。实现时可以在onReady注册监听,在onUnload移除。
  1. Page({
  2.   data: {
  3.     showCaptureWarning: false,
  4.   },
  5.   onReady() {
  6.     let that = this;
  7.     has.onUserCaptureScreen(function() {
  8.       that.setData({ showCaptureWarning: true });
  9.       setTimeout(() => {
  10.         that.setData({ showCaptureWarning: false });
  11.       }, 3000);
  12.     });
  13.   },
  14.   onUnload() {
  15.     has.offUserCaptureScreen();
  16.   }
  17. });
复制代码

四、防截屏/录屏:setVisualEffectOnCapture

如果希望在截屏或录屏时隐藏敏感内容,可以使用setVisualEffectOnCapture。将visualEffect设为hidden,窗口在截屏/录屏时会被替换为黑色画面,从而保护隐私。设为none则恢复正常。
  1. // 开启防截屏
  2. has.setVisualEffectOnCapture({
  3.   visualEffect: 'hidden', // 截屏时隐藏
  4.   success: () => {
  5.     console.info('防截屏已开启');
  6.   },
  7.   fail: (err) => {
  8.     console.error('设置失败:', err);
  9.   }
  10. });
  11. // 关闭防截屏
  12. has.setVisualEffectOnCapture({
  13.   visualEffect: 'none',
  14.   success: () => {
  15.     console.info('防截屏已关闭');
  16.   }
  17. });
复制代码

这个API有两个明显的限制:一是起始版本为2.0.1,比其他屏幕API晚很多,做功能规划时必须考虑低版本兼容;二是需要ohos.permission.PRIVACY_WINDOW权限,而且这个权限需要在AGC(AppGallery Connect)平台申请,不是普通声明就能拿到。

五、踩坑总结与API速查

根据实际使用经验,以下问题值得注意:

1. setScreenBrightness设置的亮度只在当前元服务内有效,不能依赖它做全局亮度调节。
2. setKeepScreenOn同样只作用于当前元服务,用户退出后自动恢复熄屏策略。页面销毁时最好主动关闭,养成好习惯。
3. onUserCaptureScreen只能注册一个监听函数,重复注册会覆盖。建议在页面级统一注册和移除。
4. setVisualEffectOnCapture版本要求高(2.0.1起),且需要申请PRIVACY_WINDOW权限。对金融、密码管理等强隐私场景是刚需,但要做好版本降级方案。
5. getScreenBrightness返回-1表示跟随系统设置,需要做特殊处理。

最后给出API速查表:
- 设置亮度:has.setScreenBrightness({ value });value为0-1,-1恢复系统。
- 获取亮度:has.getScreenBrightness({ success(res) });res.value为0-1或-1。
- 开启/关闭常亮:has.setKeepScreenOn({ keepScreenOn });布尔值控制。
- 截屏监听:has.onUserCaptureScreen(callback) / has.offUserCaptureScreen(callback)。
- 防截屏:has.setVisualEffectOnCapture({ visualEffect: 'hidden' | 'none' })。

ASCF的屏幕API虽然能力有限,但胜在简单直接,覆盖了亮度、常亮、截屏三个高频维度。阅读类、视频类、导航类元服务可以直接使用;防截屏能力则更适合对安全要求较高的应用。如果业务需要更底层的系统级控制,可以关注@ohos.brightness等系统模块,但那些接口的权限和复杂度会明显更高。当前API的临时生效机制虽然限制了灵活性,但也避免了元服务随意改动用户系统设置,是一种合理的设计取舍。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-1 18:09 , Processed in 0.035160 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部