Flutter for OpenHarmony三方库适配实战:screen 屏幕亮度与保持唤醒
屏幕亮度控制和保持屏幕唤醒是移动应用的常见需求,用于阅读器、视频播放、导航等场景。在 Flutter for OpenHarmony 应用开发中,screen是一个轻量级的屏幕控制插件,提供了跨平台的亮度和唤醒控制能力。screen 库为 Flutter for OpenHarmony 提供了简洁的屏幕控制能力,支持亮度调节和保持唤醒功能。API 设计简单直观,适合快速集成到阅读器、播放器等应用中
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
本文基于flutter3.27.5开发

一、screen 库概述
屏幕亮度控制和保持屏幕唤醒是移动应用的常见需求,用于阅读器、视频播放、导航等场景。在 Flutter for OpenHarmony 应用开发中,screen 是一个轻量级的屏幕控制插件,提供了跨平台的亮度和唤醒控制能力。
screen 库特点
screen 库基于 Flutter 平台接口实现,提供了以下核心特性:
亮度控制:支持获取和设置屏幕亮度,可实现阅读器护眼模式、视频播放亮度调节等功能。
保持唤醒:支持保持屏幕常亮,防止屏幕自动休眠,适用于导航、视频播放、阅读等场景。
简洁 API:提供简单直观的静态方法,无需实例化对象即可使用。
跨平台支持:统一的 API 设计,支持 Android、iOS、OpenHarmony 等多个平台。
功能支持对比
| 功能 | Android | iOS | OpenHarmony |
|---|---|---|---|
| 获取亮度 | ✅ | ✅ | ✅ |
| 设置亮度 | ✅ | ✅ | ✅ |
| 获取唤醒状态 | ✅ | ✅ | ✅ |
| 设置唤醒状态 | ✅ | ✅ | ✅ |
使用场景:电子书阅读器、视频播放器、导航应用、倒计时应用、展示类应用等。
二、安装与配置
2.1 添加依赖
在项目的 pubspec.yaml 文件中添加 screen 依赖:
dependencies:
screen:
git:
url: https://atomgit.com/openharmony-sig/fluttertpc_screen.git
然后执行以下命令获取依赖:
flutter pub get
2.2 权限配置
在 OpenHarmony 项目中,控制屏幕亮度通常不需要特殊权限,但如果需要修改系统亮度设置,可能需要相应权限。打开 ohos/entry/src/main/module.json5 文件确认权限配置。
三、核心 API 详解
3.1 Screen 类
Screen 是屏幕控制的核心类,提供静态方法控制亮度和唤醒状态。
class Screen {
static const MethodChannel _channel =
const MethodChannel('github.com/clovisnicolas/flutter_screen');
static Future<double> get brightness async;
static Future setBrightness(double brightness);
static Future<bool> get isKeptOn async;
static Future keepOn(bool on);
}
3.2 brightness 属性
brightness 属性用于获取当前屏幕亮度。
static Future<double> get brightness async
返回值:返回当前屏幕亮度值,范围 0.0 ~ 1.0。
说明:
- 如果应用设置了自定义亮度,返回应用设置的亮度值
- 如果应用使用系统亮度,返回系统当前亮度值(已转换为 0.0 ~ 1.0 范围)
使用示例:
double currentBrightness = await Screen.brightness;
print('当前亮度: $currentBrightness');
3.3 setBrightness 方法
setBrightness 方法用于设置屏幕亮度。
static Future setBrightness(double brightness)
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| brightness | double | 亮度值,范围 0.0 ~ 1.0 |
说明:
- 设置的亮度仅对当前应用窗口生效
- 不会修改系统全局亮度设置
- 退出应用后亮度设置会自动恢复
使用示例:
await Screen.setBrightness(0.5);
await Screen.setBrightness(1.0);
await Screen.setBrightness(0.0);
3.4 isKeptOn 属性
isKeptOn 属性用于获取屏幕是否保持唤醒状态。
static Future<bool> get isKeptOn async
返回值:返回 true 表示屏幕保持唤醒,false 表示正常休眠。
使用示例:
bool isKeptOn = await Screen.isKeptOn;
print('屏幕保持唤醒: $isKeptOn');
3.5 keepOn 方法
keepOn 方法用于设置屏幕是否保持唤醒。
static Future keepOn(bool on)
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| on | bool | true 保持唤醒,false 允许休眠 |
说明:
- 设置为
true后,屏幕将保持常亮,不会自动休眠 - 设置为
false后,恢复正常的屏幕超时行为 - 退出应用后设置会自动恢复
使用示例:
await Screen.keepOn(true);
await Screen.keepOn(false);
四、数据类型详解
4.1 亮度值范围
| 值 | 说明 |
|---|---|
| 0.0 | 最低亮度 |
| 0.5 | 中等亮度 |
| 1.0 | 最高亮度 |
4.2 唤醒状态
| 值 | 说明 |
|---|---|
| true | 屏幕保持唤醒 |
| false | 屏幕正常休眠 |
五、OpenHarmony 平台实现原理
5.1 原生 API 映射
| Flutter API | OpenHarmony API |
|---|---|
| brightness | window.getWindowProperties().brightness |
| setBrightness | window.setWindowBrightness() |
| isKeptOn | window.getWindowProperties().isKeepScreenOn |
| keepOn | window.setWindowKeepScreenOn() |
5.2 亮度控制实现
OpenHarmony 使用 window 模块控制窗口亮度:
onMethodCall(call: MethodCall, result: MethodResult): void {
switch (call.method) {
case "brightness":
result.success(this.getBrightness());
break;
case "setBrightness":
this.mainWindow?.setWindowBrightness(
parseFloat(call.argument("brightness"))
);
result.success(null);
break;
}
}
getBrightness(): number {
const brightness = this.mainWindow?.getWindowProperties().brightness;
if (brightness && brightness >= 0) {
return brightness;
}
let value = settings.getValueSync(
this.context,
settings.display.SCREEN_BRIGHTNESS_STATUS,
'100',
settings.domainName.DEVICE_SHARED
);
return parseFloat(value) / 255;
}
5.3 唤醒控制实现
case "isKeptOn":
let flags: boolean = this.mainWindow?.getWindowProperties().isKeepScreenOn || false;
result.success(flags);
break;
case "keepOn":
let on: boolean = call.argument("on");
if (on) {
this.mainWindow?.setWindowKeepScreenOn(true);
} else {
this.mainWindow?.setWindowKeepScreenOn(false);
}
result.success(null);
break;
5.4 Android 平台实现对比
case "brightness":
result.success(getBrightness());
break;
case "setBrightness":
double brightness = call.argument("brightness");
WindowManager.LayoutParams layoutParams =
activity.getWindow().getAttributes();
layoutParams.screenBrightness = (float)brightness;
activity.getWindow().setAttributes(layoutParams);
result.success(null);
break;
case "isKeptOn":
int flags = activity.getWindow().getAttributes().flags;
result.success((flags & FLAG_KEEP_SCREEN_ON) != 0);
break;
case "keepOn":
Boolean on = call.argument("on");
if (on) {
activity.getWindow().addFlags(FLAG_KEEP_SCREEN_ON);
} else {
activity.getWindow().clearFlags(FLAG_KEEP_SCREEN_ON);
}
result.success(null);
break;
六、MethodChannel 通信协议
6.1 方法列表
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| brightness | - | double | 获取屏幕亮度 |
| setBrightness | {“brightness”: double} | null | 设置屏幕亮度 |
| isKeptOn | - | bool | 获取唤醒状态 |
| keepOn | {“on”: bool} | null | 设置唤醒状态 |
6.2 Channel 名称
const MethodChannel _channel =
const MethodChannel('github.com/clovisnicolas/flutter_screen');
七、实战案例
7.1 完整屏幕控制示例
以下示例整合了屏幕亮度和唤醒控制的核心功能,包括:亮度调节滑块、保持唤醒开关、状态显示等。
import 'package:flutter/material.dart';
import 'package:screen/screen.dart';
void main() {
runApp(const MaterialApp(home: ScreenControlPage()));
}
class ScreenControlPage extends StatefulWidget {
const ScreenControlPage({super.key});
State<StatefulWidget> createState() => _ScreenControlPageState();
}
class _ScreenControlPageState extends State<ScreenControlPage> {
double _brightness = 0.5;
bool _isKeptOn = false;
bool _isLoading = true;
void initState() {
super.initState();
_loadScreenSettings();
}
Future<void> _loadScreenSettings() async {
try {
final brightness = await Screen.brightness;
final isKeptOn = await Screen.isKeptOn;
setState(() {
_brightness = brightness;
_isKeptOn = isKeptOn;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('加载屏幕设置失败: $e')),
);
}
}
}
Future<void> _setBrightness(double value) async {
try {
await Screen.setBrightness(value);
setState(() {
_brightness = value;
});
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('设置亮度失败: $e')),
);
}
}
}
Future<void> _toggleKeepOn(bool value) async {
try {
await Screen.keepOn(value);
setState(() {
_isKeptOn = value;
});
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('设置唤醒状态失败: $e')),
);
}
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('屏幕控制')),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildBrightnessSection(),
const SizedBox(height: 24),
_buildKeepOnSection(),
const SizedBox(height: 24),
_buildStatusSection(),
],
),
),
);
}
Widget _buildBrightnessSection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(Icons.brightness_6, size: 24),
const SizedBox(width: 8),
const Text(
'屏幕亮度',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const Spacer(),
Text(
'${(_brightness * 100).toStringAsFixed(0)}%',
style: const TextStyle(fontSize: 16),
),
],
),
const SizedBox(height: 16),
Slider(
value: _brightness,
min: 0.0,
max: 1.0,
divisions: 100,
onChanged: _setBrightness,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton.icon(
onPressed: () => _setBrightness(0.2),
icon: const Icon(Icons.brightness_low),
label: const Text('暗'),
),
TextButton.icon(
onPressed: () => _setBrightness(0.5),
icon: const Icon(Icons.brightness_medium),
label: const Text('中'),
),
TextButton.icon(
onPressed: () => _setBrightness(1.0),
icon: const Icon(Icons.brightness_high),
label: const Text('亮'),
),
],
),
],
),
),
);
}
Widget _buildKeepOnSection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
const Icon(Icons.screen_lock_portrait, size: 24),
const SizedBox(width: 8),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'保持屏幕唤醒',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 4),
Text(
'开启后屏幕将保持常亮',
style: TextStyle(fontSize: 14, color: Colors.grey),
),
],
),
),
Switch(
value: _isKeptOn,
onChanged: _toggleKeepOn,
),
],
),
),
);
}
Widget _buildStatusSection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'当前状态',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
_buildStatusRow('亮度值', _brightness.toStringAsFixed(2)),
_buildStatusRow('亮度百分比', '${(_brightness * 100).toStringAsFixed(0)}%'),
_buildStatusRow('唤醒状态', _isKeptOn ? '保持唤醒' : '正常休眠'),
],
),
),
);
}
Widget _buildStatusRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label, style: const TextStyle(color: Colors.grey)),
Text(value, style: const TextStyle(fontWeight: FontWeight.w500)),
],
),
);
}
}
代码要点说明:
| 功能模块 | 实现方式 |
|---|---|
| 亮度获取 | Screen.brightness 获取当前亮度值 |
| 亮度设置 | Screen.setBrightness(double) 设置亮度 |
| 唤醒状态获取 | Screen.isKeptOn 获取当前唤醒状态 |
| 唤醒状态设置 | Screen.keepOn(bool) 设置唤醒状态 |
| 错误处理 | try-catch 捕获异常并显示提示 |
| 状态管理 | initState 中加载初始状态 |
八、常见问题与解决方案
8.1 亮度设置无效
问题:调用 setBrightness 后屏幕亮度没有变化。
解决方案:
- 确保亮度值在 0.0 ~ 1.0 范围内
- 检查设备是否支持亮度调节
- 某些设备可能需要用户手动授权
Future<void> setBrightnessSafely(double value) async {
if (value < 0.0 || value > 1.0) {
throw ArgumentError('亮度值必须在 0.0 到 1.0 之间');
}
await Screen.setBrightness(value.clamp(0.0, 1.0));
}
8.2 保持唤醒不生效
问题:调用 keepOn(true) 后屏幕仍然会休眠。
解决方案:
- 确保应用在前台运行
- 检查设备的省电模式设置
- 某些设备可能限制了后台应用的唤醒权限
8.3 退出应用后设置未恢复
问题:退出应用后亮度或唤醒状态没有恢复。
解决方案:
在应用退出时手动恢复设置:
class ScreenManager {
static double? _originalBrightness;
static bool? _originalKeepOn;
static Future<void> saveOriginalSettings() async {
_originalBrightness = await Screen.brightness;
_originalKeepOn = await Screen.isKeptOn;
}
static Future<void> restoreOriginalSettings() async {
if (_originalBrightness != null) {
await Screen.setBrightness(_originalBrightness!);
}
if (_originalKeepOn != null) {
await Screen.keepOn(_originalKeepOn!);
}
}
}
8.4 获取亮度返回系统亮度
问题:设置亮度后,再次获取返回的是系统亮度而非应用设置值。
解决方案:
这是正常行为,应用设置的亮度仅对当前窗口生效。如果需要记住用户设置,可以自行缓存:
class BrightnessManager {
static double _currentBrightness = 0.5;
static double get currentBrightness => _currentBrightness;
static Future<void> setBrightness(double value) async {
await Screen.setBrightness(value);
_currentBrightness = value;
}
}
九、与其他库对比
| 特性 | screen | screen_brightness | wakelock |
|---|---|---|---|
| 亮度控制 | ✅ | ✅ | ❌ |
| 保持唤醒 | ✅ | ❌ | ✅ |
| API 复杂度 | 简单 | 中等 | 简单 |
| OpenHarmony 支持 | ✅ | ❌ | ✅ |
| 维护状态 | 社区维护 | 活跃开发 | 活跃开发 |
建议:
- 需要同时控制亮度和唤醒:使用
screen - 只需要亮度控制:可考虑
screen_brightness - 只需要保持唤醒:可考虑
wakelock
十、总结
screen 库为 Flutter for OpenHarmony 提供了简洁的屏幕控制能力,支持亮度调节和保持唤醒功能。API 设计简单直观,适合快速集成到阅读器、播放器等应用中。
核心要点:
- 使用静态方法直接调用,无需实例化
- 亮度值范围为 0.0 ~ 1.0
- 设置仅对当前应用窗口生效
- 退出应用后设置自动恢复
- 建议在应用启动时保存原始设置
最佳实践:
- 在应用启动时保存原始亮度设置
- 提供亮度预设值(暗、中、亮)方便用户选择
- 视频播放时自动保持屏幕唤醒
- 阅读器应用提供护眼亮度模式
- 处理异常情况,提供友好的错误提示
更多推荐


所有评论(0)