flutterflutter-audio-query

audioQuery doesn't wait for checking storage permisson


class _HomeState extends State<Home> {
  @override
  void initState() {
    super.initState();
    checkPermission();
  }

  final audioQuery = OnAudioQuery();
FutureBuilder<List<SongModel>>(
        future: audioQuery.querySongs(
          sortType: null,
          orderType: OrderType.ASC_OR_SMALLER,
          uriType: UriType.EXTERNAL,
          ignoreCase: true,
        ),

Future<void> checkPermission() async {
    if (!kIsWeb) {
      bool permissionRequest = await audioQuery.permissionsRequest();

      setState(() {});
    }
  }

i was trying to use audioQuery following tutorial on youtube, but i have error that audioQuery.querySongs() is excecute before user give a permission.

then i try to add permission check like this:

Future<void> checkPermission() async {
    if (!kIsWeb) {
      bool permissionStatus = await audioQuery.permissionsStatus();
       if (!permissionStatus) {
         await audioQuery.permissionsRequest();
       }

      setState(() {});
    }
  }

but it doesn't work. my DEBUGE CONSOLE says:

**W/le.music_playe(29628): Accessing hidden method Landroid/content/ContextWrapper;->getDisplay()Landroid/view/Display; (light greylist, linking)
W/OnAudioQueryPlugin(29628): The application doesn't have access to the library
E/AndroidRuntime(29628): FATAL EXCEPTION: main**

the first warning means Showing popup to get access to storage, but after popup show my app crash. i think it because audioQuery.querySongs() excecute before user give permission.

so how to make that function wait until checkPermission() is done. i was trying using Future.wait() but i dont understand to do it. please help me to fix this Thanks.


Solution

  • Just create a variable to hold the permission, and render the FutureBuilder conditionally

    class _HomeState extends State<Home> {
      ...
      bool hasPermission = false;
    

    and within the function, something like:

    Future<void> checkPermission() async {
      if (!kIsWeb) {
        bool permissionStatus = await audioQuery.permissionsStatus();
        if (!permissionStatus) {
          permissionStatus = await audioQuery.permissionsRequest();
        }
    
        setState(() {
          hasPermission = permissionStatus; // --> update it here..
        });
      }
    }
    

    and then:

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        ...
        hasPermission
          ? FutureBuilder<List<SongModel>>(
              future: audioQuery.querySongs(
              
              ),
              builder: (context, snapshot) {
              },
            )
          : Center(child: Text("No permissions"))
      );
    }
    

    Btw, you shouldn't instantiate the future within the future parameter since it will rerun whenever your build method repaints. Please see: