鸿蒙专家 发表于 2026-9-1 16:00:00

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

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

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

亮度控制有两个接口:setScreenBrightness用于设置亮度,getScreenBrightness用于获取当前亮度。设置时value的取值范围是0到1,0最暗,1最亮。如果传入-1,则恢复为跟随系统亮度。


// 设置亮度为50%
has.setScreenBrightness({
value: 0.5,
success: () => {
    console.info('亮度设置成功');
},
fail: (err) => {
    console.error('亮度设置失败:', err);
}
});

// 恢复系统亮度
has.setScreenBrightness({
value: -1,
success: () => {
    console.info('已恢复系统亮度');
}
});


获取当前亮度时,如果返回值是-1,说明当前亮度跟随系统,而不是一个具体的数值。代码里需要对这个特殊值做判断,避免直接用0-1的逻辑处理。


has.getScreenBrightness({
success: (res) => {
    console.info('当前亮度:', res.value);
    // value 范围 0-1,-1 表示跟随系统
},
fail: (err) => {
    console.error('获取亮度失败:', err);
}
});


一个典型场景是阅读模式。进入阅读模式时,先保存当前亮度,再把亮度调到0.3;退出时恢复之前保存的亮度。实现逻辑如下:


Page({
data: {
    isReadingMode: false,
    originalBrightness: -1,
},
toggleReadingMode() {
    let that = this;
    if (that.data.isReadingMode) {
      // 退出阅读模式,恢复亮度
      has.setScreenBrightness({
      value: -1,
      success: () => {
          that.setData({ isReadingMode: false });
          has.showToast({ title: '已退出阅读模式' });
      }
      });
    } else {
      // 先保存当前亮度
      has.getScreenBrightness({
      success: (res) => {
          that.setData({ originalBrightness: res.value });
          // 设置低亮度
          has.setScreenBrightness({
            value: 0.3,
            success: () => {
            that.setData({ isReadingMode: true });
            has.showToast({ title: '已进入阅读模式' });
            }
          });
      }
      });
    }
}
});


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

二、屏幕常亮:setKeepScreenOn

setKeepScreenOn用于控制屏幕是否保持常亮。参数keepScreenOn为true时开启,false时关闭。接口本身很简单,但要注意生命周期管理。


// 开启常亮
has.setKeepScreenOn({
keepScreenOn: true,
success: () => {
    console.info('屏幕常亮已开启');
},
fail: (err) => {
    console.error('设置失败:', err);
}
});

// 关闭常亮
has.setKeepScreenOn({
keepScreenOn: false,
success: () => {
    console.info('屏幕常亮已关闭');
}
});


最典型的场景是视频播放。播放时开启常亮,暂停时关闭,页面销毁时也要记得关闭,避免异常退出导致亮屏状态残留。


Page({
data: {
    isPlaying: false,
},
onVideoPlay() {
    this.setData({ isPlaying: true });
    has.setKeepScreenOn({ keepScreenOn: true });
},
onVideoPause() {
    this.setData({ isPlaying: false });
    has.setKeepScreenOn({ keepScreenOn: false });
},
onUnload() {
    // 页面销毁时关闭常亮
    has.setKeepScreenOn({ keepScreenOn: false });
}
});


导航场景也常用常亮。导航页面在onShow时开启常亮,onHide时关闭,保证用户在不触碰屏幕时也能持续看到路线。


Page({
onShow() {
    // 导航页面开启常亮
    has.setKeepScreenOn({
      keepScreenOn: true,
      success: () => {
      console.info('导航模式:屏幕常亮');
      }
    });
},
onHide() {
    // 页面隐藏时关闭常亮
    has.setKeepScreenOn({ keepScreenOn: false });
}
});


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

三、截屏监听:onUserCaptureScreen

ASCF提供onUserCaptureScreen来监听用户截屏行为,offUserCaptureScreen用于移除监听。注册回调后,只要用户触发系统截屏,回调就会执行。


// 注册截屏监听
const onCapture = function() {
console.info('用户截屏了');
// 可以在这里做安全提示
};
has.onUserCaptureScreen(onCapture);

// 移除监听
has.offUserCaptureScreen(onCapture);


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

实际场景中,截屏监听常用于安全提示。比如金融类页面或私密聊天页面,用户截屏后立即弹出一条警示,提示“截屏已记录”。实现时可以在onReady注册监听,在onUnload移除。


Page({
data: {
    showCaptureWarning: false,
},
onReady() {
    let that = this;
    has.onUserCaptureScreen(function() {
      that.setData({ showCaptureWarning: true });
      setTimeout(() => {
      that.setData({ showCaptureWarning: false });
      }, 3000);
    });
},
onUnload() {
    has.offUserCaptureScreen();
}
});


四、防截屏/录屏:setVisualEffectOnCapture

如果希望在截屏或录屏时隐藏敏感内容,可以使用setVisualEffectOnCapture。将visualEffect设为hidden,窗口在截屏/录屏时会被替换为黑色画面,从而保护隐私。设为none则恢复正常。


// 开启防截屏
has.setVisualEffectOnCapture({
visualEffect: 'hidden', // 截屏时隐藏
success: () => {
    console.info('防截屏已开启');
},
fail: (err) => {
    console.error('设置失败:', err);
}
});

// 关闭防截屏
has.setVisualEffectOnCapture({
visualEffect: 'none',
success: () => {
    console.info('防截屏已关闭');
}
});


这个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的临时生效机制虽然限制了灵活性,但也避免了元服务随意改动用户系统设置,是一种合理的设计取舍。

热心网友7 发表于 2026-9-1 19:00:00

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

这篇帖子写得很实用,尤其是把阅读模式和视频播放的典型场景直接贴出代码,对刚接触ASCF屏幕API的开发者来说非常友好。亮度-1表示跟随系统这个细节确实容易忽略,提醒得很到位。另外关于setKeepScreenOn要配合页面生命周期管理这个点,我也遇到过类似问题,页面销毁或隐藏时忘记关闭常亮,导致后续状态不对,帖子里专门强调这点很关键。想顺便问一下,截屏监听和防截屏这两个API在元服务里使用有什么权限或限制吗?最近正好在做金融类场景,想提前了解下。

热心网友6 发表于 2026-9-1 19:05:00

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

楼主的总结很实用,正好最近也在折腾鸿蒙元服务的屏幕控制。亮度这块确实要注意 `-1` 跟随系统的特殊值,之前没判断就直接拿来当比例用,结果在部分设备上出现异常。还有个感受就是 `setKeepScreenOn` 和页面生命周期的绑定很重要,特别是用户中途切后台再回来,如果 `onShow` 里没重新开启,常亮就失效了,导致视频播放中断。楼主提到的“切到其他应用后亮度自动恢复”这个点也提醒了我,之前还误以为能全局改,后来查了才知道元服务能力有限。另外想问下,截屏监听和防截屏这两个API在异步回调里处理时,有没有遇到过偶发不生效的情况?我这边在部分机型上测试,防截屏偶尔会延迟几毫秒才生效,不知道是不是需要配合其他机制兜底。

热心网友3 发表于 2026-9-1 19:10:00

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

感谢楼主分享,这几个API确实很实用。我最近也在做元服务,正好遇到亮度调节和常亮的需求,看完这个帖子思路清晰多了。有个小问题想请教:亮度设置只在当前元服务内生效,那如果用户切到后台再回来,需要重新设置吗?另外如果是视频播放场景,切后台再回来常亮状态是否会丢失?期待楼主后续内容。
页: [1]
查看完整版本: 鸿蒙ASCF屏幕控制API实践:亮度调节常亮与截屏监听