flutter_downloaded_audio_play_in_notification 1.0.1
flutter_downloaded_audio_play_in_notification: ^1.0.1 copied to clipboard
A Flutter plugin for playing downloaded audio files in notifications with background playback support and terminated state handling.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'notification_service.dart';
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
await notificationService.handleBackgroundIncoming(
message.data,
message.notification?.title,
message.notification?.body,
);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// IMPORTANT: Register background handler here, NOT inside service
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
// Initialize custom service AFTER background handler registered
await notificationService.init();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Notification Audio Test',
home: const TestScreen(),
);
}
}
class TestScreen extends StatefulWidget {
const TestScreen({super.key});
@override
State<TestScreen> createState() => _TestScreenState();
}
class _TestScreenState extends State<TestScreen> {
String _status = 'Ready to test';
String _token = 'Loading...';
@override
void initState() {
super.initState();
_loadToken();
}
Future<void> _loadToken() async {
final token = await FirebaseMessaging.instance.getToken();
setState(() {
_token = token ?? 'No token available';
});
}
Future<void> _sendTestNotification() async {
setState(() {
_status = 'Use external tool to send notification';
});
// Show instructions
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Use curl command or Firebase Console to send notification with audio'),
duration: Duration(seconds: 5),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Notification Audio Test'),
backgroundColor: Colors.red,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
color: Colors.grey[100],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
const Text(
'FCM Token:',
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
SelectableText(
_token,
style: const TextStyle(fontSize: 12),
textAlign: TextAlign.center,
),
],
),
),
),
const SizedBox(height: 32),
Text(
'Status: $_status',
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
ElevatedButton.icon(
onPressed: _sendTestNotification,
icon: const Icon(Icons.notifications),
label: const Text('Send Test Notification (External)'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: () async {
await NotificationService().stopAudio();
},
icon: const Icon(Icons.stop_circle),
label: const Text('STOP AUDIO & TERMINATE APP'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
textStyle:
const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
const SizedBox(height: 32),
const Card(
color: Colors.yellow,
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Test Instructions:',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
Text('1. Kill the app completely (swipe from recent apps)'),
Text('2. Send notification with audio using curl/Firebase'),
Text('3. Wait for audio to start playing'),
Text('4. Tap the notification'),
Text('5. Audio should stop when app opens'),
SizedBox(height: 8),
Text(
'OR use the red button to simulate termination',
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.red),
),
],
),
),
),
],
),
),
);
}
}