Flutter桌面屏幕状态监测插件desktop_screenstate的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter桌面屏幕状态监测插件desktop_screenstate的使用

Desktop ScreenState 是一个用于Flutter桌面应用的插件,它提供了准确判断屏幕是否开启或关闭的功能,同时还能检测屏幕是否锁定或解锁。

平台支持

Linux macOS Windows

macOS

无需任何更改。

Windows

需要对以下文件进行更改:

windows/runner/flutter_window.h

#ifndef RUNNER_FLUTTER_WINDOW_H_
#define RUNNER_FLUTTER_WINDOW_H_

#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <winuser.h>
#include <memory>

#include "win32_window.h"

// 一个仅用于托管Flutter视图的窗口。
class FlutterWindow : public Win32Window {
 public:
  // 创建一个新的托管|project|运行的Flutter视图的FlutterWindow。
  explicit FlutterWindow(const flutter::DartProject& project);
  virtual ~FlutterWindow();

 protected:
  // Win32Window:
  bool OnCreate() override;
  void OnDestroy() override;
  LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
                         LPARAM const lparam) noexcept override;

 private:
  // 要运行的项目。
  flutter::DartProject project_;
  HPOWERNOTIFY power_notification_handle_ = nullptr;
  // 由该窗口托管的Flutter实例。
  std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
};

#endif  // RUNNER_FLUTTER_WINDOW_H_

windows/runner/flutter_window.cpp

#include "flutter_window.h"

#include <optional>
#include <wtsapi32.h>
#include "flutter/generated_plugin_registrant.h"
#pragma comment( lib, "wtsapi32.lib" )

FlutterWindow::FlutterWindow(const flutter::DartProject& project)
    : project_(project) {}

FlutterWindow::~FlutterWindow() {
  if (power_notification_handle_) {
    UnregisterPowerSettingNotification(power_notification_handle_);
  }
}

bool FlutterWindow::OnCreate() {
  if (!Win32Window::OnCreate()) {
    return false;
  }

  RECT frame = GetClientArea();

  // 这里的尺寸必须与窗口尺寸匹配,以避免不必要的表面创建/销毁。
  flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
      frame.right - frame.left, frame.bottom - frame.top, project_);
  // 确保控制器的基本设置成功。
  if (!flutter_controller_->engine() || !flutter_controller_->view()) {
    return false;
  }
  RegisterPlugins(flutter_controller_->engine());
  SetChildContent(flutter_controller_->view()->GetNativeWindow());
  power_notification_handle_ = RegisterPowerSettingNotification(GetHandle(), &GUID_CONSOLE_DISPLAY_STATE, DEVICE_NOTIFY_WINDOW_HANDLE);
  WTSRegisterSessionNotification(GetHandle(), NOTIFY_FOR_THIS_SESSION);
  return true;
}

void FlutterWindow::OnDestroy() {
  if (flutter_controller_) {
    flutter_controller_ = nullptr;
  }

  Win32Window::OnDestroy();
}

LRESULT
FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
                              WPARAM const wparam,
                              LPARAM const lparam) noexcept {
  // 给Flutter及其插件机会处理窗口消息。
  if (flutter_controller_) {
    std::optional<LRESULT> result =
        flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
                                                      lparam);
    if (result) {
      return *result;
    }
  }

  switch (message) {
    case WM_FONTCHANGE:
      flutter_controller_->engine()->ReloadSystemFonts();
      break;
  }

  return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
}

Linux

此插件依赖于gnome-screensaver来提供屏幕状态信息。

Linux重要提示:

如果你的Linux系统上没有安装gnome-screensaver,请在使用此插件之前先安装。插件的功能取决于gnome-screensaver的存在。

sudo apt-get install gnome-screensaver

入门指南

  1. desktop_screenstate添加到你的pubspec.yaml文件中。
  desktop_screenstate: $latest_version
  1. 然后你可以使用DesktopScreenState.instance.isActive来监听窗口激活事件。
final ValueListenable<bool> event = DesktopScreenState.instance.isActive;

final bool active = event.value;

event.addListener(() {
  debugPrint("屏幕是否开启或关闭: ${event.value}");
});
  1. 现在你可以利用DesktopScreenState.instance.state获取当前屏幕的状态:
final ScreenState state = DesktopScreenState.instance.state;

switch (state) {
  case ScreenState.awaked:
    debugPrint("屏幕已开启");
    break;
  case ScreenState.sleep:
    debugPrint("屏幕已睡眠");
    break;
  case ScreenState.locked:
    debugPrint("屏幕已锁定");
    break;
  case ScreenState.unlocked:
    debugPrint("屏幕已解锁");
    break;
}

DesktopScreenState实例提供了一个枚举ScreenState,其可能的值如下:

  • awaked
  • sleep
  • locked
  • unlocked

完整示例代码

import 'dart:developer';

import 'package:desktop_screenstate/desktop_screenstate.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final String _platformVersion = 'Unknown';
  final _screenstatePlugin = DesktopScreenState.instance;

  [@override](/user/override)
  void initState() {
    DesktopScreenState.instance.isActive.addListener(() {
      log(DesktopScreenState.instance.isActive.value.toString());
    });
    super.initState();
  }

  // 平台消息是异步的,所以我们初始化时使用异步方法。

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: ValueListenableBuilder<ScreenState>(
          valueListenable: _screenstatePlugin.isActive,
          builder: (context, value, child) => Center(
            child: Text('屏幕状态: $value'),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter桌面屏幕状态监测插件desktop_screenstate的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter桌面屏幕状态监测插件desktop_screenstate的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 desktop_screenstate 插件来监测 Flutter 桌面应用屏幕状态的代码示例。这个插件可以帮助你检测屏幕的锁定状态、工作区状态等信息。

首先,确保你的 Flutter 项目已经添加了 desktop_screenstate 依赖。你可以在 pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  desktop_screenstate: ^最新版本号  # 请替换为实际的最新版本号

然后运行 flutter pub get 来获取依赖。

接下来,你可以在你的 Flutter 应用中使用这个插件。以下是一个简单的示例,展示如何监听屏幕状态的变化:

import 'package:flutter/material.dart';
import 'package:desktop_screenstate/desktop_screenstate.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  ScreenState _currentScreenState = ScreenState.unknown;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
    _listenToScreenState();
  }

  @override
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    _screenStateSubscription?.cancel();
    super.dispose();
  }

  void _listenToScreenState() {
    _screenStateSubscription = ScreenState.screenStateStream.listen((state) {
      setState(() {
        _currentScreenState = state;
      });
      print('Screen state changed to: $_currentScreenState');
    });
  }

  StreamSubscription<ScreenState>? _screenStateSubscription;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Screen State Monitor'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'Current Screen State: $_currentScreenState',
                style: TextStyle(fontSize: 24),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 引入依赖:导入了 desktop_screenstate 插件。
  2. 创建状态管理:使用 StatefulWidgetState 来管理屏幕状态。
  3. 监听屏幕状态变化:在 initState 方法中,使用 ScreenState.screenStateStream 来监听屏幕状态的变化。每当屏幕状态变化时,更新 _currentScreenState 状态并打印新的状态。
  4. 显示当前屏幕状态:在 build 方法中,使用 Text 小部件显示当前的屏幕状态。

这个示例展示了如何使用 desktop_screenstate 插件来监测 Flutter 桌面应用的屏幕状态。你可以根据实际需求进一步扩展和自定义这个示例。

回到顶部