import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; /// Trägt fertige Musikdateien in den öffentlichen Musikordner von Android ein. /// /// Nötig, weil der Bibliotheks-Scan auf Android über den MediaStore läuft: /// Songs, die dort nicht stehen, werden beim nächsten Scan als verschwunden /// markiert. Nebeneffekt: heruntergeladene Musik ist auch in anderen Apps da. class MediaStore { const MediaStore({this.channel = _standardKanal}); static const _standardKanal = MethodChannel('de.baka.melo/media_store'); final MethodChannel channel; /// Verschiebt [quellPfad] nach `Music/Melo` und meldet die Datei dem /// MediaStore. [volume] wählt den Datenträger (siehe [speicherOrte]); /// ohne Angabe nimmt Android den internen Speicher. /// Gibt den neuen Pfad zurück, oder `null` wenn es nicht klappt. Future veroeffentliche({ required String quellPfad, required String titel, String? kuenstler, String? volume, }) async { try { return await channel.invokeMethod('publishAudio', { 'sourcePath': quellPfad, 'title': titel, 'artist': kuenstler, 'volume': volume, }); } on PlatformException catch (e) { debugPrint('MediaStore-Eintrag fehlgeschlagen: ${e.message}'); return null; } on MissingPluginException { // Desktop/Tests: dort gibt es keinen MediaStore. return null; } } /// Alle Datenträger, auf denen Musik landen kann — interner Speicher und, /// falls eingelegt, SD-Karten. Future> speicherOrte() async { try { final roh = await channel.invokeListMethod>('listVolumes'); if (roh == null || roh.isEmpty) return const [_intern]; return [ for (final eintrag in roh) SpeicherOrt( name: eintrag['name'] as String, beschreibung: eintrag['beschreibung'] as String, ), ]; } on PlatformException catch (e) { debugPrint('Speicherorte nicht lesbar: ${e.message}'); return const [_intern]; } on MissingPluginException { // Desktop/Tests: dort gibt es nur den einen Ordner. return const [_intern]; } } } /// Ein Datenträger für heruntergeladene Musik. [name] ist der MediaStore-Name /// des Datenträgers, [beschreibung] das, was der Nutzer liest. class SpeicherOrt { const SpeicherOrt({required this.name, required this.beschreibung}); final String name; final String beschreibung; } const _intern = SpeicherOrt(name: 'external_primary', beschreibung: 'Interner Speicher');