skip to Main Content

I am new to flutter/dart. I am trying to develop a Music Player application.
Problem is when my application trying to retrieve all mp3 files from downloads folder.

It lists all audio(mp3) files on emulator, but when I installed APK on my device the button is stuck when pressed.

What can I do ?

[Emulator : Android 13 Tiramisu]
[Device: Android 11 R]

//requesting permission code
requestPermission() async {
    // Web platform don't support permissions methods.
    if (!kIsWeb) {
      bool permissionStatus = await _audioQuery.permissionsStatus();
      if (!permissionStatus) {
        await _audioQuery.permissionsRequest();
      }
      setState(() {});
    }
  }

//Button code
IconButton(
  icon: const Icon(Icons.menu_rounded, size: 30,), 
    onPressed: () {
      Navigator.push(context,MaterialPageRoute(builder: (context) => const Songs()));
},)
class _SongsState extends State<Songs> {

body: SafeArea(
          minimum: const EdgeInsets.fromLTRB(5, 10, 5, 5),
          child: Column(
            children: [
              Expanded(
                  child:ListView.builder(
                      itemCount: getSongList()[0].length,
                      itemBuilder: (BuildContext context, int index) {
                        return ListTile(
                          title: Text(getSongList()[1][index].split('/').last,style:
                          const TextStyle(
                              fontSize: 21
                          ),),
                          leading: IconButton(onPressed: (){
                            Navigator.push(context,MaterialPageRoute(
                                builder: (context) => music_player(selectedSong: getSongList()[1],selectedIndex:index)
                            ));
                          },
                              icon: const Icon(Icons.play_circle,size: 30,)),
                        

  // Removed all brackets to reduce code for SO question

  // function to retrieve all mp3's
  List getSongList(){

    Directory dir = Directory('/storage/emulated/0/Download/');
    String mp3Path = dir.toString();

    List<FileSystemEntity> _files;
    List<FileSystemEntity> _songs = [];
    List<String> _songpaths = [];
    _files = dir.listSync(recursive: true, followLinks: false);

    for(FileSystemEntity entity in _files) {
      String path = entity.path;
      if(path.endsWith('.mp3')) {
        _songs.add(entity);
        _songpaths.add(path);
      }
    }
    return [_songs,_songpaths];
  }

}

Screenshot of App

2

Answers


  1. Basic problem is you are trying to get list of audio files in build method in sync.

    You need to do it as async task. Something like this would work…

    class Songs extends StatefulWidget {
      const Songs({super.key});
      @override
      State<StatefulWidget> createState() => _SongsState();
    }
    
    class _SongsState extends State<Songs> {
      List<FileSystemEntity>? songs;
      List<String>? songpaths;
    
      StreamSubscription? _fetchSongs;
    
      @override
      void initState() {
        super.initState();
        _fetchSongsAsyc();
      }
    
      Future<void> _fetchSongsAsyc() async {
        Directory dir = Directory('/storage/emulated/0/Download/');
        String mp3Path = dir.toString();
    
        List<FileSystemEntity> files;
        songs = [];
        songpaths = [];
        _fetchSongs = dir.list(recursive: true, followLinks: false).listen(
          (entity) {
            String path = entity.path;
            if (path.endsWith('.mp3')) {
              songs?.add(entity);
              songpaths?.add(path);
            }
          },
          onDone: () {
            _fetchSongs = null;
            setState(() {});
          },
        );
      }
    
      @override
      void dispose() {
        _fetchSongs?.cancel();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            minimum: const EdgeInsets.fromLTRB(5, 10, 5, 5),
            child: Builder(builder: (context) {
              if (songs == null) {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              }
              return Column(
                children: [
                  Expanded(
                    child: ListView.builder(
                        itemCount: songs?.length ?? 0,
                        itemBuilder: (BuildContext context, int index) {
                          return ListTile(
                              title: Text(
                                songpaths![index].split('/').last,
                                style: const TextStyle(fontSize: 21),
                              ),
                              leading: IconButton(
                                  onPressed: () {
                                    Navigator.push(context,
                                        MaterialPageRoute(builder: (context) {
                                      Navigator.push(
                                          context,
                                          MaterialPageRoute(
                                              builder: (context) => music_player(
                                                  selectedSong: songpaths,
                                                  selectedIndex: index)));
                                    }));
                                  },
                                  icon: const Icon(
                                    Icons.play_circle,
                                    size: 30,
                                  )));
                        }),
                  ),
                ],
              );
            }),
          ),
        );
      }
    }
    
    
    Login or Signup to reply.
  2. Try this to get music list

    void getFiles() async { //asyn function to get list of files
      List<StorageInfo> storageInfo = await PathProviderEx.getStorageInfo();
      var root = storageInfo[0].rootDir; //storageInfo[1] for SD card, geting the root directory
      var fm = FileManager(root: Directory(root)); //
      files = await fm.filesTree( 
        excludedPaths: ["/storage/emulated/0/Android"],
        extensions: ["mp3"] //optional, to filter files, list only mp3 files
      );
      setState(() {}); //update the UI
    }  
    

    Then to show music list

    files == null? Text("Searching Files"):
           ListView.builder(  //if file/folder list is grabbed, then show here
              itemCount: files?.length ?? 0,
              itemBuilder: (context, index) {
                    return Card(
                      child:ListTile(
                         title: Text(files[index].path.split('/').last),
                         leading: Icon(Icons.audiotrack),
                         trailing: Icon(Icons.play_arrow, color: Colors.redAccent,),
                         onTap: (){
                            // you can add Play/push code over here
                         },
                      )  
    

    Kindly check this article
    Also you can use this package for more features

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search