Flutter Android App使用audio_service,杀死应用后音频未停止的问题求助
Flutter Android App使用audio_service,杀死应用后音频未停止的问题求助
大家好,我正在开发一个基于Flutter的安卓电台应用,目前遇到了一个棘手的问题:当音乐正在播放时,如果我“杀掉”应用进程,音频并不会停止,还会继续播放。我尝试查找了相关的解决方案,但还是没能结合自己的项目解决问题,所以想把代码贴出来,麻烦大家帮我看看哪里出了问题。
我当前使用audio_service和just_audio来处理音频播放,已经配置了安卓通知通道并设置了androidNotificationOngoing: true,但问题依然存在。
main.dart 代码
late AudioHandler audioHandler; void main() async { audioHandler = await AudioService.init( builder: () => AudioPlayerHandler(), config: const AudioServiceConfig( androidNotificationChannelId: 'com.radio.cyprus.audio', androidNotificationChannelName: 'Radio Playback', androidNotificationOngoing: true, ), ); await JustAudioBackground.init( androidNotificationChannelId: 'com.radio.cyprus.audio', androidNotificationChannelName: 'Radio Playback', androidNotificationOngoing: true, ); WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); MobileAds.instance.initialize(); // 禁用横屏 SystemChrome.setPreferredOrientations( [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); // HttpOverrides.global = MyHttpOverrides(); runApp(const MyApp()); DependencyInjection.init(); }
radio_stations.dart 代码
import 'dart:io'; import 'package:audio_service/audio_service.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_carplay/flutter_carplay.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:just_audio/just_audio.dart'; import 'package:overlay_support/overlay_support.dart'; import 'package:radio_stream_player/radio_card.dart'; import 'ad_helper.dart'; import 'firebase_options.dart'; class RadioStations extends StatefulWidget { const RadioStations({super.key}); @override State<RadioStations> createState() => _RadioStationsState(); } class _RadioStationsState extends State<RadioStations> { final player = AudioPlayer(); dynamic currentlyPlaying; int adCounter = 0; InterstitialAd? interstitialAd; bool interstitialAdLoaded = false; bool nowPlaying = false; final CollectionReference _collectionRef = FirebaseFirestore.instance.collection('stations'); List documentIDsList = []; List<dynamic> stationList = []; late Future<dynamic> stationData; int currentStation = 0; CPConnectionStatusTypes connectionStatus = CPConnectionStatusTypes.unknown; final FlutterCarplay _flutterCarplay = FlutterCarplay(); Future<List> getFirestoreStations() async { try { await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform); QuerySnapshot querySnapshot = await _collectionRef.orderBy("name", descending: true).get(); stationList = querySnapshot.docs.map((doc) => doc.data()).toList(); documentIDsList = querySnapshot.docs.map((doc) => doc.id).toList(); return stationList; } catch (e, s) { debugPrint("Error fetching Firebase data: $e"); debugPrint("Stack trace: $s"); return []; } } Future<void> loadCarPlay(List<dynamic> stationList) async { FlutterCarplay.setRootTemplate( animated: true, rootTemplate: CPListTemplate( title: "Radio Cyprus", systemIcon: '', sections: [ CPListSection( header: "Cyprus Radio Stations", items: stationList .map( (station) => CPListItem( image: 'assets/radio.png', text: station['name'], detailText: station['categories'].toString(), onPress: (complete, self) { setState(() { currentlyPlaying = station; }); checkStation(); complete(); }, ), ) .toList(), ), ], ), ); _flutterCarplay.forceUpdateRootTemplate(); } Future<void> initApp() async { loadCarPlay(stationList); } void onCarplayConnectionChange(CPConnectionStatusTypes status) { // 车载连接状态变化时的处理逻辑 setState(() async { connectionStatus = status; if (status == CPConnectionStatusTypes.connected) { await loadCarPlay(stationList); } showSimpleNotification( ListTile( leading: const Icon(Icons.directions_car), title: Text('Carplay Status: ${CPEnumUtils.stringFromEnum(status)}'), ), position: NotificationPosition.top, duration: const Duration(seconds: 3), slideDismissDirection: DismissDirection.up, background: Colors.blueGrey, ); }); } @override void initState() { stationData = getFirestoreStations(); if (!kIsWeb) { loadInterstitialAd(); if (Platform.isIOS) { WidgetsBinding.instance.addPostFrameCallback((_) => initApp()); _flutterCarplay.addListenerOnConnectionChange(onCarplayConnectionChange); _flutterCarplay.forceUpdateRootTemplate(); } } super.initState(); } @override void dispose() { player.dispose(); if (Platform.isIOS) { _flutterCarplay.removeListenerOnConnectionChange(); } interstitialAd?.dispose(); super.dispose(); } void checkStation() { player.stop(); stationList.asMap().forEach((index, items) { if (items == currentlyPlaying) { if (currentlyPlaying['isPlay'] == true) { setState(() { stationList[index]['isPlay'] = false; nowPlaying = false; player.pause(); }); } else { setState(() { stationList[index]['isPlay'] = true; nowPlaying = true; }); player.setUrl(currentlyPlaying['url']).then((value) { player.play(); }); } } else { setState(() { stationList[index]['isPlay'] = false; }); } }); } }
我自己也有个疑问:在radio_stations.dart里我直接用了AudioPlayer实例player控制播放,但同时在main.dart里又初始化了AudioHandler,会不会是这里的使用方式冲突了?比如应该统一通过audioHandler来管理播放逻辑,这样AudioService才能在应用被杀掉时正确处理停止音频的操作?
内容来源于stack exchange
相关产品推荐
相关产品推荐

