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.

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:

  • Flutter FutureBuilder keeps Firing and rebuilding. It Generates a New Random Number on Every Rebuild – How can I Prevent This?

Leave a Comment