目录

Implementing Background Recording

Starting from API version 9, the background continuous task development feature is supported. An app can configure a background continuous task to enable background recording.

Background recording refers to the scenario where an app continues to capture audio after starting a recording task in the foreground and then moving to the background. Typical scenarios include meeting minutes, voice memos, interview recordings, and other services that require long-duration recording.

Background recording involves microphone capture and background running. An app must simultaneously meet the requirements for microphone permission, recording capability implementation, background continuous task declaration, and system control. Recording must not be started without the user's awareness or authorization.

Constraints

How to Develop

For details about how to implement the recording feature, see Using AudioCapturer for Audio Recording (ArkTS), (Recommended) Using OHAudio for Audio Recording (C/C++), or Using AVRecorder to Record Audio (ArkTS). When the app needs to switch to the background for continuous recording, it must also request a recording-type continuous task (ArkTS).

  1. Declare the background recording mode.

    In the module.json5 configuration file, declare the audioRecording background mode for the UIAbility that needs to perform background recording.

    {
      "abilities": [
        {
          "name": "EntryAbility",
          "backgroundModes": [
            "audioRecording"
          ]
        }
      ]
    }
  2. Start the recording task.

    The app must start the recording task in the foreground. After the recording starts, the app can switch to the background to continue recording. Starting recording directly in the background will fail.

    Before recording starts, the app must confirm that the user has explicitly triggered the recording operation, and handle exception scenarios such as microphone permission not granted, device being occupied, and storage path being unavailable. For details about recording development, see Audio Recording Development.

    For scenarios where app background recording is interrupted by other audio streams and cannot be recovered, the following solution is recommended:

    • When app recording is interrupted in the background and start fails upon receiving a focus restoration notification, a dialog can be displayed to remind the user to open the app again and manually restart recording.
    • Use the audio recording API setIndependentAudioSessionStrategy with AudioSessionBehaviorFlags set to MUTE_WHEN_INTERRUPTED. This configures the recording stream focus policy to the mute-when-interrupted mode. When recording is stopped or paused due to interruption by another app, it enters a muted recording state where the recorded audio is silent. After the other app completes its recording action, audible data recording resumes.
  3. Apply for a recording-type continuous task.

    When recording needs to continue running in the background, the app must apply for a continuous task of the AUDIO_RECORDING type so that the system can identify that the background task matches the recording service.

    import { BusinessError } from '@kit.BasicServicesKit';
    import { backgroundTaskManager } from '@kit.BackgroundTasksKit'
    import { wantAgent, WantAgent } from '@kit.AbilityKit'
    // ...
    
      // Start the continuous task.
      startContinuousTask(context: Context) {
        let wantAgentInfo: wantAgent.WantAgentInfo = {
          // List of actions to be executed after the notification is tapped.
          // Add the bundleName and abilityName of the app to be started.
          wants: [
            {
              bundleName: 'com.example.backgroundmusic',
              abilityName: 'MainAbility'
            }
          ],
          // Specify that the action after tapping the notification bar message is to start an ability.
          actionType: wantAgent.OperationType.START_ABILITY,
          // A private value defined by the user.
          requestCode: 0,
          // Action execution attributes after the notification is tapped.
          actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
        };
    
        try {
          // Obtain the WantAgent object through the getWantAgent method in the wantAgent module.
          wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => {
            try {
              let list: string[] = ['audioPlayback', 'audioRecording'];
              backgroundTaskManager.startBackgroundRunning(context, list, wantAgentObj)
                .then(() => {
                  console.info('Operate startBackgroundRunning succeeded');
                })
                .catch((error: BusinessError) => {
                  console.error(`Failed to operate startBackgroundRunning. code is ${error.code} message is ${error.message}`);
                });
            } catch (error) {
              console.error(`Failed to operate startBackgroundRunning. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
            };
          });
        } catch (error) {
          console.error(`Failed to operate getWantAgent. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`);
        }
      }

    When a continuous task fails to start, the app must avoid continuing to run in background recording mode. It should stop recording or guide the user back to the foreground. For the complete process of requesting and canceling a continuous task, see Continuous Task (ArkTS).

  4. Stop recording and release resources.

    When the user stops recording, recording is abnormally interrupted, or the service ends, the app must call the release API of AudioCapturer to stop recording, release audio capture resources, and simultaneously cancel the continuous task of the recording type.

    // Cancel the continuous task.
    stopContinuousTask(context: Context) {
      backgroundTaskManager.stopBackgroundRunning(context).then(() => {
        console.info(`Succeeded in operating stopBackgroundRunning.`);
      }).catch((err: BusinessError) => {
        console.error(`Failed to operate stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`);
      });
    }