鸿蒙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的临时生效机制虽然限制了灵活性,但也避免了元服务随意改动用户系统设置,是一种合理的设计取舍。
Re: 鸿蒙ASCF屏幕控制API实践:亮度调节常亮与截屏监听
这篇帖子写得很实用,尤其是把阅读模式和视频播放的典型场景直接贴出代码,对刚接触ASCF屏幕API的开发者来说非常友好。亮度-1表示跟随系统这个细节确实容易忽略,提醒得很到位。另外关于setKeepScreenOn要配合页面生命周期管理这个点,我也遇到过类似问题,页面销毁或隐藏时忘记关闭常亮,导致后续状态不对,帖子里专门强调这点很关键。想顺便问一下,截屏监听和防截屏这两个API在元服务里使用有什么权限或限制吗?最近正好在做金融类场景,想提前了解下。Re: 鸿蒙ASCF屏幕控制API实践:亮度调节常亮与截屏监听
楼主的总结很实用,正好最近也在折腾鸿蒙元服务的屏幕控制。亮度这块确实要注意 `-1` 跟随系统的特殊值,之前没判断就直接拿来当比例用,结果在部分设备上出现异常。还有个感受就是 `setKeepScreenOn` 和页面生命周期的绑定很重要,特别是用户中途切后台再回来,如果 `onShow` 里没重新开启,常亮就失效了,导致视频播放中断。楼主提到的“切到其他应用后亮度自动恢复”这个点也提醒了我,之前还误以为能全局改,后来查了才知道元服务能力有限。另外想问下,截屏监听和防截屏这两个API在异步回调里处理时,有没有遇到过偶发不生效的情况?我这边在部分机型上测试,防截屏偶尔会延迟几毫秒才生效,不知道是不是需要配合其他机制兜底。Re: 鸿蒙ASCF屏幕控制API实践:亮度调节常亮与截屏监听
感谢楼主分享,这几个API确实很实用。我最近也在做元服务,正好遇到亮度调节和常亮的需求,看完这个帖子思路清晰多了。有个小问题想请教:亮度设置只在当前元服务内生效,那如果用户切到后台再回来,需要重新设置吗?另外如果是视频播放场景,切后台再回来常亮状态是否会丢失?期待楼主后续内容。
页:
[1]