Getting Album Artwork in flutter

Issue

I am trying to create a music app. I managed to get all the songs list but I cannot seem to get album artwork from the song metadata. I am using flutter_audio_query: ^0.3.5+6 plugin for this.
I cannot get the artwork by using songs[index].albumArtwork. It always returns null instead of the image path. What is the problem with my code?

Here is my code

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_audio_query/flutter_audio_query.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final FlutterAudioQuery audioQuery = FlutterAudioQuery();
  List<SongInfo> songs = [];

  @override
  void initState() {
    super.initState();
    checkPermission();
    getAllSongs();
  }

  Future<void> getAllSongs() async {
    songs = await audioQuery.getSongs();
  }

  Future<void> checkPermission() async {
    if (await Permission.storage.request().isGranted) {
      setState(() {});
    } else {
      _showDialog();
    }
  }

  void _showDialog() async {
    return showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Warning'),
          content: SingleChildScrollView(
            child: ListBody(
              children: const <Widget>[
                Text('The app needs storage permission in order to work'),
              ],
            ),
          ),
          actions: <Widget>[
            TextButton(
              child: const Text('OK'),
              onPressed: () async {
                Navigator.of(context).pop();
                await checkPermission();
              },
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF3C3C3C),
      appBar: AppBar(
        elevation: 0.0,
        centerTitle: true,
        toolbarHeight: 64.0,
        leading: Icon(
          Icons.music_note_rounded,
        ),
        actions: [
          IconButton(
            onPressed: () {},
            icon: Icon(Icons.search_rounded),
          ),
        ],
        backgroundColor: Colors.transparent,
        title: Text(
          "All Songs",
          style: GoogleFonts.expletusSans(
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
      body: ListView.builder(
        itemCount: songs.length,
        itemBuilder: (context, index) {
          return ListTile(
            leading: Image.asset(
              songs[index].albumArtwork != null
                  ? songs[index].albumArtwork
                  : "assets/placeholder.png",
            ),
            title: Text(songs[index].title),
            subtitle: Text(songs[index].artist),
          );
        },
      ),
    );
  }
}

Solution

Sometimes albumArtwork will return a null value. In this case you need to use [FlutterAudioQuery().getArtwork()].

Use ResourceType.ALBUM to get album image and ResourceType.SONG to song image.

Example:

 // check if artistArtPath isn't available.

 (song.artwork == null)

    ? FutureBuilder<Uint8List>(
      future: audioQuery.getArtwork(
        type: ResourceType.SONG, id: song.id),
        builder: (_, snapshot) {
          if (snapshot.data == null)
            return Container(
              height: 250.0,
              child: Center(
                child: CircularProgressIndicator(),
              ),
            );
            
            return CardItemWidget(
              height: 250.0,
              title: artist.name,
              // The image bytes
              // You can use Image.memory widget constructor 
              // or MemoryImage image provider class to load image from bytes
              // or a different approach.
              rawImage: snapshot.data,
            );
          }) :
          // or you can load image from File path if available.
          Image.file( File( artist.artistArtPath ) )

Answered By – Lucas Josino

Answer Checked By – Marie Seifert (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *