You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.0 KiB
156 lines
5.0 KiB
import 'dart:async';
|
|
import 'package:audio_service/audio_service.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:synchronized/synchronized.dart';
|
|
import 'my_audio_handler.dart';
|
|
|
|
class AudioServiceManager extends GetxService {
|
|
static AudioServiceManager get to => Get.find();
|
|
MyAudioHandler? _audioHandler;
|
|
bool _isInitialized = false;
|
|
final _lock = Lock();
|
|
|
|
// 添加一个标志,表示是否已经尝试过初始化
|
|
bool _hasAttemptedInit = false;
|
|
|
|
// 添加一个计时器,用于定期检查服务状态
|
|
Timer? _serviceCheckTimer;
|
|
|
|
Future<AudioServiceManager> init() async {
|
|
print('初始化 AudioServiceManager');
|
|
|
|
if (_isInitialized) {
|
|
print('AudioServiceManager 已经初始化');
|
|
return this;
|
|
}
|
|
|
|
// 如果已经尝试过初始化但失败了,不再重试
|
|
if (_hasAttemptedInit) {
|
|
print('AudioServiceManager 之前初始化失败,尝试重新初始化');
|
|
// 重置标志,允许重新初始化
|
|
_hasAttemptedInit = false;
|
|
}
|
|
|
|
_hasAttemptedInit = true;
|
|
|
|
try {
|
|
// 使用锁确保初始化的原子性
|
|
await _lock.synchronized(() async {
|
|
if (_isInitialized) return;
|
|
|
|
// 使用 AudioService.init 初始化音频服务
|
|
_audioHandler = await AudioService.init<MyAudioHandler>(
|
|
builder: () => MyAudioHandler(),
|
|
config: AudioServiceConfig(
|
|
androidNotificationChannelId: 'com.example.deep_voice.channel.audio',
|
|
androidNotificationChannelName: 'Deep Voice Audio Service',
|
|
// 使用应用图标作为通知图标,确保这个图标存在
|
|
androidNotificationIcon: 'mipmap/ic_launcher',
|
|
// 修复配置冲突:当androidStopForegroundOnPause为true时,androidNotificationOngoing才能为true
|
|
androidNotificationOngoing: false,
|
|
// 设置为true,允许在暂停时停止前台服务,避免与androidNotificationOngoing冲突
|
|
androidStopForegroundOnPause: true,
|
|
androidShowNotificationBadge: true,
|
|
notificationColor: Colors.blue,
|
|
fastForwardInterval: const Duration(seconds: 10),
|
|
rewindInterval: const Duration(seconds: 10),
|
|
preloadArtwork: false,
|
|
),
|
|
);
|
|
|
|
// 注册自定义音频处理器
|
|
await Get.put(_audioHandler!, permanent: true);
|
|
|
|
_isInitialized = true;
|
|
print('AudioServiceManager 初始化成功');
|
|
|
|
// 启动定期检查服务状态的计时器
|
|
_startServiceCheckTimer();
|
|
});
|
|
|
|
return this;
|
|
} catch (e) {
|
|
print('AudioServiceManager初始化失败: $e');
|
|
_isInitialized = false; // 确保失败时重置状态
|
|
|
|
// 延迟5秒后尝试重新初始化
|
|
Future.delayed(Duration(seconds: 5), () {
|
|
print('尝试重新初始化 AudioServiceManager');
|
|
_hasAttemptedInit = false;
|
|
init();
|
|
});
|
|
|
|
return this; // 即使失败也返回实例,避免空指针异常
|
|
}
|
|
}
|
|
|
|
// 启动定期检查服务状态的计时器
|
|
void _startServiceCheckTimer() {
|
|
_serviceCheckTimer?.cancel();
|
|
_serviceCheckTimer = Timer.periodic(Duration(minutes: 5), (timer) {
|
|
_checkAndRestartServiceIfNeeded();
|
|
});
|
|
}
|
|
|
|
// 检查服务状态,如果需要则重启服务
|
|
Future<void> _checkAndRestartServiceIfNeeded() async {
|
|
if (!_isInitialized || _audioHandler == null) {
|
|
print('服务检查:AudioServiceManager 未初始化,尝试重新初始化');
|
|
_hasAttemptedInit = false;
|
|
await init();
|
|
return;
|
|
}
|
|
print('服务检查:AudioServiceManager 已初始化,服务状态: $_isInitialized');
|
|
}
|
|
|
|
// 获取音频处理器
|
|
MyAudioHandler? get audioHandler => _audioHandler;
|
|
|
|
// 发送媒体按钮事件
|
|
Future<void> sendMediaButtonEvent() async {
|
|
if (_audioHandler != null) {
|
|
try {
|
|
print('发送媒体按钮事件');
|
|
await _audioHandler!.customAction('media_button');
|
|
} catch (e) {
|
|
print('发送媒体按钮事件失败: $e');
|
|
|
|
// 如果发送失败,尝试重新初始化服务
|
|
_isInitialized = false;
|
|
_hasAttemptedInit = false;
|
|
await init();
|
|
}
|
|
} else {
|
|
print('AudioHandler 未初始化,无法发送媒体按钮事件');
|
|
// 尝试重新初始化
|
|
_isInitialized = false;
|
|
_hasAttemptedInit = false;
|
|
await init();
|
|
}
|
|
}
|
|
|
|
// 手动触发媒体按钮事件(用于测试)
|
|
Future<void> triggerMediaButtonEvent() async {
|
|
print('手动触发媒体按钮事件');
|
|
await sendMediaButtonEvent();
|
|
}
|
|
|
|
@override
|
|
void onClose() async {
|
|
_isInitialized = false;
|
|
_serviceCheckTimer?.cancel();
|
|
|
|
// 停止现有的音频处理器
|
|
if (_audioHandler != null) {
|
|
try {
|
|
await _audioHandler!.stop();
|
|
} catch (e) {
|
|
print('停止 AudioHandler 失败: $e');
|
|
}
|
|
_audioHandler = null;
|
|
}
|
|
|
|
super.onClose();
|
|
}
|
|
}
|