Flutter媒体按键检测插件media_key_detector的使用

Flutter媒体按键检测插件media_key_detector的使用

简介

media_key_detector 插件用于在按下媒体按键时触发事件。在 MacOS 上,它会将您的应用注册为一个 “Now Playable App”(现在可播放的应用),允许其响应来自键盘、耳机或媒体遥控器的媒体事件。

特性

  • 捕获并触发以下键的事件:
    • 播放/暂停
    • 上一首/倒退
    • 下一首/快进

背景

通常情况下,通过常规键盘方法(如 RawKeyListener 或 FocusNode)捕获媒体按键是可行的,但在 Windows 和 Linux 上工作良好。然而,在 MacOS 上,这些键事件无法被检测到,并且经常会发送给未激活的窗口,例如 Music 应用。

使用步骤

1. 添加依赖

运行以下命令添加 media_key_detector 包:

flutter pub add media_key_detector

或者手动编辑 pubspec.yaml 文件并运行 flutter pub get

dependencies:
  media_key_detector: ^latest_version

2. 导入包

在 Dart 文件中导入插件:

import 'package:media_key_detector/media_key_detector.dart';

使用示例

void _mediaKeyListener(MediaKey mediaKey) {
  debugPrint('$mediaKey pressed');
}

[@override](/user/override)
void initState() {
  super.initState();
  mediaKeyDetector.addListener(_mediaKeyListener);
}

[@override](/user/override)
void dispose() {
  mediaKeyDetector.removeListener(_mediaKeyListener);
  super.dispose();
}

/// 如果你需要根据插件来跟踪播放状态,请使用以下两个方法。
/// 在 MacOS/iOS 上,这有助于在 "Command Center" 中显示状态。

/// 获取当前媒体是否正在播放。注意,它默认是 "暂停" 的状态,
/// 所以如果你的应用在打开时播放媒体,你应该调用
/// [mediaKeyDetector.setIsPlaying(true)]
Future<bool> getIsMediaPlaying() async {
  return await mediaKeyDetector.getIsPlaying();
}

/// 当用户按下媒体键时,应用程序会跟踪播放状态,
/// 但有些情况(例如在 UI 界面上按下播放按钮)可能需要你自己设置。
Future play() async {
  return await mediaKeyDetector.setIsPlaying(isPlaying: true);
}

完整示例

import 'dart:async';

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

void main() => runApp(const MyApp());

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(home: HomePage());
  }
}

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

  [@override](/user/override)
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String? _platformName;
  bool _isPlaying = false;
  Map<MediaKey, bool> keyPressed = {
    MediaKey.playPause: false,
    MediaKey.rewind: false,
    MediaKey.fastForward: false,
  };

  void _mediaKeyListener(MediaKey mediaKey) {
    debugPrint('$mediaKey pressed');

    mediaKeyDetector
        .getIsPlaying()
        .then((playing) => setState(() => _isPlaying = playing));

    if (keyPressed[mediaKey] == false) {
      setState(() => keyPressed[mediaKey] = true);
      Timer(const Duration(seconds: 3), () {
        setState(() => keyPressed[mediaKey] = false);
      });
    }
  }

  Future<void> _togglePlayPause() async {
    setState(() => _isPlaying = !_isPlaying);
    await mediaKeyDetector.setIsPlaying(isPlaying: _isPlaying);
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    mediaKeyDetector.addListener(_mediaKeyListener);
  }

  [@override](/user/override)
  void dispose() {
    mediaKeyDetector.removeListener(_mediaKeyListener);
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    final colors = Theme.of(context).colorScheme;

    return Scaffold(
      appBar: AppBar(title: const Text('MediaKeyDetector Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
                '按你的IO设备上的媒体按钮来高亮对应的图标。'),
            const Text(
                '按播放/暂停按钮来向插件发送当前播放信息。'),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Icon(
                  Icons.fast_rewind_rounded,
                  size: 40,
                  color: (keyPressed[MediaKey.rewind] ?? false)
                      ? colors.inversePrimary
                      : colors.onBackground,
                ),
                IconButton.filled(
                  onPressed: _togglePlayPause,
                  style:
                      IconButton.styleFrom(backgroundColor: colors.secondary),
                  icon: Icon(
                    _isPlaying
                        ? Icons.pause_circle_rounded
                        : Icons.play_circle_rounded,
                    size: 40,
                    color: (keyPressed[MediaKey.playPause] ?? false)
                        ? colors.inversePrimary
                        : colors.onPrimary,
                  ),
                ),
                Icon(
                  Icons.fast_forward_rounded,
                  size: 40,
                  color: (keyPressed[MediaKey.fastForward] ?? false)
                      ? colors.inversePrimary
                      : colors.onBackground,
                ),
              ],
            ),
            Text('当前是否正在播放: $_isPlaying'),
            if (_platformName == null)
              const SizedBox.shrink()
            else
              Text(
                '平台名称: $_platformName',
                style: Theme.of(context).textTheme.headlineSmall,
              ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () async {
                if (!context.mounted) return;
                try {
                  final result = await getPlatformName();
                  setState(() => _platformName = result);
                } catch (error) {
                  if (!context.mounted) return;
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      backgroundColor: Theme.of(context).primaryColor,
                      content: Text('$error'),
                    ),
                  );
                }
              },
              child: const Text('获取平台名称'),
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter媒体按键检测插件media_key_detector的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter媒体按键检测插件media_key_detector的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


media_key_detector 是一个 Flutter 插件,用于检测设备上的媒体按键(如播放、暂停、下一曲、上一曲等)。这个插件可以帮助你在 Flutter 应用中监听并响应这些按键事件。

安装插件

首先,你需要在 pubspec.yaml 文件中添加 media_key_detector 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  media_key_detector: ^0.0.1  # 使用最新版本

然后运行 flutter pub get 来安装插件。

使用插件

1. 导入插件

在你的 Dart 文件中导入 media_key_detector 插件:

import 'package:media_key_detector/media_key_detector.dart';

2. 监听媒体按键事件

你可以使用 MediaKeyDetector 类来监听媒体按键事件。以下是一个简单的示例:

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

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

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _mediaKey = 'No media key pressed';

  [@override](/user/override)
  void initState() {
    super.initState();
    _initMediaKeyDetector();
  }

  void _initMediaKeyDetector() {
    MediaKeyDetector.onMediaKey.listen((MediaKeyEvent event) {
      setState(() {
        _mediaKey = event.toString();
      });
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Media Key Detector Example'),
        ),
        body: Center(
          child: Text(_mediaKey),
        ),
      ),
    );
  }
}
回到顶部