When recording audio you need access to the devices microphone and possibly its storage.
Sounds does not manage permissions for you. You must ensure that the appropriate permissions are obtained.
The package permission_handler provides a convenient set of methods for manageing permissions.
When requesting permissions the OS will display a prompt to the user. I generally recommend that you only prompt the user for the required permissions at the point in time that they require them.
To allow you complete control over the timing of the permission request to the user you can provide a call back to the requestPermission argument which is called when the user clicks the 'record' button. Recording will not start until the callback completes.
onStart
The onStart method is called when recording starts.
This example is from the example app. It demonstrates how to create a Recorder SoundRecorderUI linked to a SoundPlayerUI.
The example demonstrates how to build a UI which allows a user to record audio and then immediately play it back.
The example also uses requestPermissions to display an explanatory dialog to the user before the OS displays its standard permission dialog.
The RecorderPlaybackController is responsible for coordinating the recording and playback so that only one can occur at a time.
import'dart:async';import'dart:core';import'package:flutter/material.dart';import'package:sounds/sounds.dart';import'package:permission_handler/permission_handler.dart';voidmain() {var recordingPath =Track.tempFile(MediaFormat.aacADTS);runApp(SoundExampleApp._internal(recordingPath));}classSoundExampleAppextendsStatelessWidget {finalTrack _track;//SoundExampleApp._internal(String recordingPath): _track =Track.fromFile(recordingPath, mediaFormat:MediaFormat.aacAdts);@overrideWidgetbuild(BuildContext context) {returnMaterialApp( title:'Welcome to Flutter', home:Scaffold( appBar:AppBar( title:Text('Welcome to Flutter'), ), body:buildBody(), ), ); }WidgetbuildBody() {// link the recorder and player so you can record// and then playback the message.// Note: the recorder and player MUST share the same track.returnRecorderPlaybackController( child:Column( children: [/// Add the recorderSoundRecorderUI(/// the track to record into. _track,/// callback for when recording needs permissions requestPermissions: requestPermissions, ),Padding( padding:constEdgeInsets.all(10),// add the player child:SoundPlayerUI.fromTrack(_track), ) ], )); }/// Callback for when the recorder needs permissions to record /// to the [track].Future<bool> requestPermissions(BuildContext context, Track track) async {var granted =false;/// change this to true if the track doesn't use /// external storage on android.var usingExternalStorage =false;// Request Microphone permission if neededprint('storage: ${await Permission.microphone.status}');var microphoneRequired =!awaitPermission.microphone.isGranted;var storageRequired =false;if (usingExternalStorage) {/// only required if track is on external storageif (Permission.storage.status ==PermissionStatus.undetermined) {print('You are probably missing the storage permission ''in your manifest.'); } storageRequired = usingExternalStorage &&!awaitPermission.storage.isGranted; }/// build the 'reason' why and what we are asking permissions for.if (microphoneRequired || storageRequired) {var both =false;if (microphoneRequired && storageRequired) { both =true; }var reason ="To record a message we need permission ";if (microphoneRequired) { reason +="to access your microphone"; }if (both) { reason +=" and "; }if (storageRequired) { reason +="to store a file on your phone"; } reason +=".";if (both) { reason +=" \n\nWhen prompted click the 'Allow' button on ""each of the following prompts."; } else { reason +=" \n\nWhen prompted click the 'Allow' button."; }/// tell the user we are about to ask for permissions.if (awaitshowAlertDialog(context, reason)) {var permissions =<Permission>[];if (microphoneRequired) permissions.add(Permission.microphone);if (storageRequired) permissions.add(Permission.storage);/// ask for the permissions.await permissions.request();/// check the user gave us the permissions. granted =awaitPermission.microphone.isGranted &&awaitPermission.storage.isGranted;if (!granted) grantFailed(context); } else { granted =false;grantFailed(context); } } else { granted =true; }// we already have the required permissions.return granted; }/// Display a snackbar saying that we can't record due to lack of permissions.voidgrantFailed(BuildContext context) {var snackBar =SnackBar( content:Text('Recording cannot start as you did not allow ''the required permissions'));// Find the Scaffold in the widget tree and use it to show a SnackBar.Scaffold.of(context).showSnackBar(snackBar); }///Future<bool> showAlertDialog(BuildContext context, String prompt) {// set up the buttonsWidget cancelButton =TextButton( child:Text("Cancel"), onPressed: () =>Navigator.of(context).pop(false), );Widget continueButton =TextButton( child:Text("Continue"), onPressed: () =>Navigator.of(context).pop(true), );// set up the AlertDialogvar alert =AlertDialog( title:Text("Recording Permissions"), content:Text(prompt), actions: [ cancelButton, continueButton, ], );// show the dialogreturnshowDialog<bool>( context: context, builder: (context) {return alert; }, ); }}