import 'dart:io'; import 'package:drift/drift.dart'; import 'package:on_audio_query/on_audio_query.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; import 'package:uuid/uuid.dart'; import 'database.dart'; const _uuid = Uuid(); /// Android-Scan über MediaStore (der einzige zuverlässige Weg ab Android 11, /// da Scoped Storage direkten Dateizugriff blockiert). Findet automatisch alle /// Musik auf dem Gerät. Schreibt in dieselbe DB wie der Desktop-Scan, /// UUID-stabil über den Dateipfad. Future scanAndroidMediaStore( MeloDb db, { Directory? coverDir, void Function(int done, int total)? onProgress, }) async { final audioQuery = OnAudioQuery(); final existing = {for (final s in await db.allSongs()) s.path: s}; final covers = coverDir ?? Directory(p.join((await getApplicationSupportDirectory()).path, 'covers')); await covers.create(recursive: true); final all = await audioQuery.querySongs( sortType: SongSortType.TITLE, orderType: OrderType.ASC_OR_SMALLER, uriType: UriType.EXTERNAL, ); final songs = all.where((s) => s.isMusic ?? true).toList(); final now = DateTime.now().millisecondsSinceEpoch; final companions = []; final livePaths = []; var done = 0; for (final s in songs) { livePaths.add(s.data); final prev = existing[s.data]; final id = prev?.id ?? _uuid.v4(); var coverPath = prev?.coverPath; if (coverPath == null) { final art = await audioQuery.queryArtwork(s.id, ArtworkType.AUDIO, size: 512); if (art != null && art.isNotEmpty) { final f = File(p.join(covers.path, '$id.img')); await f.writeAsBytes(art); coverPath = f.path; } } companions.add(SongsCompanion.insert( id: id, path: s.data, title: s.title, artist: Value(s.artist == '' ? null : s.artist), album: Value(s.album), durationMs: Value(s.duration), coverPath: Value(coverPath), dateAddedMs: prev?.dateAddedMs ?? (s.dateAdded != null ? s.dateAdded! * 1000 : now), updatedAtMs: now, )); onProgress?.call(++done, songs.length); } await db.upsertSongs(companions); await db.markMissing(livePaths, now); return companions.length; }