Adding a Custom Ringtone to a Notification
Starting from API version 12, applications can use custom notification ringtones when publishing notifications. The audio resources for these ringtones must be pre-included in the application. Starting from API version 24, the system has enhanced this field, allowing applications to use non-preloaded audio resources as notification ringtones, such as audio downloaded from the internet or user-generated audio files.
API Description
A custom ringtone can be specified by carrying the sound field in NotificationRequest. If this field is not specified, the system default ringtone is used.
- Resource file: Preloaded audio files in the application. Resource files must be placed in the resources/rawfile directory. Use the direct filename when configuring.
- Sandbox file: Audio files downloaded from the internet or generated by the user. Must be placed in the files directory or its subdirectories in the EL1 area of the sandbox directory. The input format is uri::{fileUri}, where fileUri is the path obtained via getUriFromPath.
Supported formats: m4a, aac, mp3, ogg, wav, flac, amr, ...
Table 1 API for publishing notifications
| API | Description |
|---|---|
| publish(request: NotificationRequest): Promise<void> | Publishes a notification. |
How to Develop
-
Import modules.
import { notificationManager } from '@kit.NotificationKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { contextConstant, common } from '@kit.AbilityKit'; import fs from '@ohos.file.fs'; import fileUri from '@ohos.file.fileuri'; const TAG: string = '[SpecifiedCustomizedRingtone]'; const DOMAIN_NUMBER: number = 0xFF00; const SOUND_FILE_NAME: string = 'ringtone_demo.mp3'; // Replace with your actual audio file. -
Prepare audio resources.
Scenario 1: Use audio resources preloaded in the application.
(1) Place the audio resources in the resources/rawfile directory of the project.
(2) Create the sound information for the notification.let soundFile: string = SOUND_FILE_NAME; // Replace it with the corresponding audio file in the resources/rawfile directory.Scenario 2: Use audio resources in the sandbox.
(1) Generate the sandbox audio resource path.
// Generate the sandbox audio resource path. const uiContext: UIContext = this.getUIContext(); let context: Context | undefined = uiContext.getHostContext() as common.UIAbilityContext; if (!context) { hilog.error(DOMAIN_NUMBER, TAG, 'Context is not initialized.'); return; } const applicationContext: common.ApplicationContext = context.getApplicationContext(); applicationContext.area = contextConstant.AreaMode.EL1; // Must be in the EL1 sandbox. const sandboxDir: string = applicationContext.filesDir; let sandboxFilePath: string = sandboxDir + '/' + SOUND_FILE_NAME;(2) Place internet-downloaded or user-generated audio resources in the files directory or its subdirectories in the EL1 area of the sandbox directory. The example below copies audio from resources/rawfile to the specified sandbox directory.
// Copy the audio file in the resources/rawfile/ directory to the files directory of the application sandbox EL1. try { let rawFileData: Uint8Array = context.resourceManager.getRawFileContentSync(SOUND_FILE_NAME); if (!fs.accessSync(sandboxDir)) { fs.mkdirSync(sandboxDir, true); } const file = fs.openSync(sandboxFilePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY); fs.writeSync(file.fd, rawFileData.buffer); fs.closeSync(file); hilog.info(DOMAIN_NUMBER, TAG, 'copy file to sandbox success.'); } catch (error) { hilog.error(DOMAIN_NUMBER, TAG, `copy file to sandbox error: ${JSON.stringify(error)}`); return; }(3) Create the sound information for the notification.
// Obtain the URI of the sandbox file. let sandboxFileUri: string = fileUri.getUriFromPath(sandboxFilePath) let soundFile: string = 'uri::' + sandboxFileUri; // The value must start with uri:: and cannot contain '../' or '/..'. -
Publish a notification with a custom ringtone.
let notificationRequest: notificationManager.NotificationRequest = { id: 0, notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION, content: { notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, normal: { title: 'title', text: 'text', additionalText: 'test_additionalText' } }, sound: soundFile } notificationManager.publish(notificationRequest).then(() => { hilog.info(DOMAIN_NUMBER, TAG, `Succeeded in publishing notification.`); }).catch((err: BusinessError) => { hilog.error(DOMAIN_NUMBER, TAG, `Failed to publish notification. Code is ${err.code}, message is ${err.message}`); });
Constraints
- When an application uses non-preloaded audio resources as notification ringtones, the URI resource path specified in the sound field of NotificationRequest cannot contain "../" or "/..", and must start with "uri::".
- When an application uses non-preloaded audio resources as notification ringtones, the audio files must be placed in the files directory of the application sandbox EL1 area.