1# RingtoneLibrary组件 2 3- [简介](#section1158716411637) 4- [目录](#section161941989596) 5- [使用说明](#usage-guidelines) 6- [相关仓](#section1533973044317) 7 8## 简介<a name="section1158716411637"></a> 9**ringtone\_library** 仓库提供了一系列易用的接口用于设定及获取系统铃音信息。 10**ringtone\_library** 提供了标准DataShareExtension接口,支持存储及查询通过SystemSoundManager设置的自定义来电/闹钟/短信/系统通知铃音文件。 11系统应用及音乐开放能力RingtoneKit通过SystemSoundManager设置及查询自定义铃音,非系统应用通过音乐开放能力RingtoneKit设置及查询自定义铃音。 12 13**图1** ringtonelibrary组件架构图 14 15 16支持能力列举如下: 17- 读取铃音内容 18- 存储和删除自定义铃音 19- 读取铃音列表,包含系统铃音和自定义铃音 20- 扫描系统预制铃音目录 21- 支持应用静默访问铃音库 22 23## 目录<a name="section161941989596"></a> 24仓库目录结构如下: 25``` 26/foundation/multimedia/ringtone_library/ # 铃音库组件代码 27├── frameworks # 框架代码 28├── interfaces # 接口代码 29│ └── inner_api # 内部native接口 30├── LICENSE # 证书文件 31├── services # 铃音库服务实现 32│ ├── ringtone_backup # 铃音库备份升级服务 33│ ├── ringtone_data_extension # 扩展插件接口 34│ ├── ringtone_dfx # DFX实现 35│ ├── ringtone_helper # 辅助类 36│ └── ringtone_scanner # 扫描功能实现 37└── test # 测试代码 38``` 39 40## 使用说明<a name="usage-guidelines"></a> 41### 概述 42提供铃音列表的增、删、改、查等接口,可以通过Uri("datashare:///ringtone/ringtone")对铃音列表进行操作。 43接口参数主要有对象类型的Uri、DataSharePredicates和DataShareValuesBucket等。 44 45使用接口功能前,需要先获取DataShareHelper 46```cpp 47auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 48auto remoteObj = saManager->GetSystemAbility(systemAbilityId); 49std::shared_ptr<DataShare::DataShareHelper> datashareHelper = DataShare::DataShareHelper::Creator(remoteObj, "datashare:///ringtone/ringtone"); 50``` 51 52### 新增铃音接口 53#### datashareHelper->Insert(const Uri &uri, const DataShareValuesBucket &value); 54 55- 参数描述 56 57 | 名称 | 读写属性 | 类型 | 必填 | 描述 | 58 | -------- | -------- | ---------------------- | ---- | ------------------------------ | 59 | uri | 只读 | Uri& | 是 | 铃音库操作Uri("datashare:///ringtone/ringtone") | 60 | value | 只读 | DataShareValuesBucket& | 是 | 数据库字段key-value对象 | 61 62- 返回值 63 64 来电铃音id 65 66- 示例 67 ```cpp 68 Uri ringtoneUri("datashare:///ringtone/ringtone"); 69 int32_t index = 0; 70 const int32_t count = 10; 71 const int64_t ringtoneSize = 1022; 72 const int type = 2; 73 const int64_t addedTime = 1559276453; 74 const int64_t modifiedTime = 1559276455; 75 const int64_t takenTime = 1559276457; 76 const int durationTime = 112; 77 DataShareValuesBucket valuesBucket; 78 valuesBucket.Put(RINGTONE_COLUMN_DATA, 79 static_cast<string>("/path_to_target/test_ringtone.ogg")); 80 valuesBucket.Put(RINGTONE_COLUMN_SIZE, static_cast<int64_t>(ringtoneSize)); 81 valuesBucket.Put(RINGTONE_COLUMN_DISPLAY_NAME, static_cast<string>("test_ringtone.ogg"); 82 valuesBucket.Put(RINGTONE_COLUMN_TITLE, static_cast<string>("test_ringtone")); 83 valuesBucket.Put(RINGTONE_COLUMN_MEDIA_TYPE, static_cast<int>(type)); 84 valuesBucket.Put(RINGTONE_COLUMN_TONE_TYPE, static_cast<int>(type)); 85 valuesBucket.Put(RINGTONE_COLUMN_MIME_TYPE, static_cast<string>("ogg")); 86 valuesBucket.Put(RINGTONE_COLUMN_SOURCE_TYPE, static_cast<int>(1)); 87 valuesBucket.Put(RINGTONE_COLUMN_DATE_ADDED, static_cast<int64_t>(addedTime)); 88 valuesBucket.Put(RINGTONE_COLUMN_DATE_MODIFIED, static_cast<int64_t>(modifiedTime)); 89 valuesBucket.Put(RINGTONE_COLUMN_DATE_TAKEN, static_cast<int64_t>(takenTime)); 90 valuesBucket.Put(RINGTONE_COLUMN_DURATION, static_cast<int>(durationTime)); 91 valuesBucket.Put(RINGTONE_COLUMN_SHOT_TONE_TYPE, static_cast<int>(1)); 92 valuesBucket.Put(RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, static_cast<int>(type)); 93 valuesBucket.Put(RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE, static_cast<int>(1)); 94 valuesBucket.Put(RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE, static_cast<int>(type)); 95 valuesBucket.Put(RINGTONE_COLUMN_RING_TONE_TYPE, static_cast<int>(1)); 96 valuesBucket.Put(RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, static_cast<int>(type)); 97 valuesBucket.Put(RINGTONE_COLUMN_ALARM_TONE_TYPE, static_cast<int>(1)); 98 valuesBucket.Put(RINGTONE_COLUMN_ALARM_TONE_SOURCE_TYPE, static_cast<int>(type)); 99 int32_t ret = dataShareHelper->Insert(ringtoneUri, valuesBucket); 100 ``` 101 102### 删除铃音接口 103#### datashareHelper->Delete(const Uri &uri, const DataSharePredicates &predicates); 104 105- Delete参数描述 106 107 | 名称 | 读写属性 | 类型 | 必填 | 描述 | 108 | -------- | -------- | ---------------------- | ---- | ------------------------------ | 109 | uri | 只读 | Uri& | 是 | 铃音库操作Uri("datashare:///ringtone/ringtone") | 110 | condition | 只读 | DataSharePredicates& | 是 | 数据库删除条件 | 111 112- 返回值 113 114 删除的铃音数量 115 116- 示例 117 118 ```cpp 119 Uri ringtoneUri("datashare:///ringtone/ringtone"); 120 DataShare::DataSharePredicates deletePredicates; 121 deletePredicates.SetWhereClause(RINGTONE_COLUMN_TONE_ID + " = ? "); 122 deletePredicates.SetWhereArgs({ to_string(1) }); 123 int32_t ret = g_dataShareHelper->Delete(ringtoneUri, deletePredicates); 124 ``` 125 126### 修改铃音接口 127#### datashareHelper->Update(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value); 128 129- Update参数描述 130 131 | 名称 | 读写属性 | 类型 | 必填 | 描述 | 132 | -------- | -------- | ---------------------- | ---- | ------------------------------ | 133 | uri | 只读 | Uri& | 是 | 具体操作的uri | 134 | condition | 只读 | DataSharePredicates& | 是 | 数据库更新条件 | 135 | value | 只读 | DataShareValuesBucket& | 是 | 数据库字段key-value对象 | 136 137- 返回值 138 139 修改的铃音数量 140 141- 示例 142 ```cpp 143 Uri ringtoneUri("datashare:///ringtone/ringtone"); 144 DataShare::DataSharePredicates updatePredicates; 145 updatePredicates.SetWhereClause(RINGTONE_COLUMN_TONE_ID + " = ? "); 146 updatePredicates.SetWhereArgs({ to_string(1) }); 147 DataShareValuesBucket updateValuesBucket; 148 updateValuesBucket.Put(RINGTONE_COLUMN_SHOT_TONE_TYPE, 0); 149 updateValuesBucket.Put(RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, 0); 150 int32_t ret = dataShareHelper->Update(ringtoneUri, deletePredicates, updateValuesBucket); 151 ``` 152 153### 查询铃音接口 154#### datashareHelper->Query(const Uri &uri, const DataSharePredicates &predicates, std::vector<std::string> &columns, DatashareBusinessError &businessError); 155 156- Query参数描述 157 158 | 名称 | 读写属性 | 类型 | 必填 | 描述 | 159 | -------- | -------- | ---------------------- | ---- | ------------------------------ | 160 | uri | 只读 | Uri& | 是 | 铃音库操作Uri("datashare:///ringtone/ringtone") | 161 | condition | 只读 | DataSharePredicates& | 是 | 查询条件 | 162 | resultColumns | 只读 | std::vector<std::string>& | 是 | 需要查询的列字段名称 | 163 | businessError | 只读 | DatashareBusinessError& | 是 | 异常代码 | 164 165- 返回值 166 数据库ResultSet结果集 167 168- 示例 169 ```cpp 170 Uri ringtoneUri("datashare:///ringtone/ringtone"); 171 int errCode = 0; 172 DatashareBusinessError businessError; 173 DataSharePredicates queryPredicates; 174 queryPredicates.EqualTo(RINGTONE_COLUMN_SHOT_TONE_TYPE, to_string(1)); 175 vector<string> columns = { 176 { RINGTONE_COLUMN_TONE_ID }, 177 { RINGTONE_COLUMN_DISPLAY_NAME }, 178 { RINGTONE_COLUMN_DATE_ADDED }, 179 { RINGTONE_COLUMN_SHOT_TONE_TYPE } 180 }; 181 auto resultSet = dataShareHelper->Query(ringtoneUri, queryPredicates, columns, &businessError); 182 ``` 183 184### 静默访问能力 185- 能力描述 186 187 为了降低数据提供方拉起次数,提高访问速度,OpenHarmony提供了一种不拉起数据提供方直接访问数据库的方式,即静默数据访问。 188 铃音库作为数据提供方在module.json5中的proxyData节点定义要共享的表的标识、读写权限、基本信息,在应用侧申请xx权限后,就可以实现不拉起铃音库进程访问铃音库数据 189 190- 数据提供方参数配置 191 192 module.json配置样例: 193 194 当应用适配requiredReadPermission && requiredWritePermission中所需要的权限后,通过uri即可对数据库进行读写操作。 195 196 ```cpp 197 "proxyDatas": [ 198 { 199 "uri":"datashareproxy://com.ohos.ringtonelibrary.ringtonelibrarydata/entry/ringtone_library/SimCardSetting", 200 "requiredReadPermission":"ohos.permission.ACCESS_CUSTOM_RINGTONE", 201 "requiredWritePermission":"ohos.permission.ACCESS_CUSTOM_RINGTONE", 202 "metadata": { 203 "name": "dataProperties", 204 "resource": "$profile:rdb_meta_simcard_setting" 205 } 206 }, 207 ] 208 ``` 209 210 - 铃音库每张表的uri定义请参考ringtone_proxy_uri.h文件 211 212 代码示例: 213 ```cpp 214 const std::string RINGTONE_LIBRARY_PROXY_DATA_URI_SIMCARD_SETTING = 215 "datashare:///com.ohos.ringtonelibrary.ringtonelibrarydata/entry/ringtone_library/SimCardSetting?Proxy=true"; 216 ``` 217- 数据访问方 218 219 铃音框架静默访问接口CreateDataShareHelperUri 220 221 铃音框架需要先去校验权限应用是否存在ACCESS_CUSTOM_RINGTONE权限,如果不存在该权限,则会使用dataShare方式拉起铃音库进程 222 223 铃音框架静默访问铃音库代码示例: 224 ```cpp 225 Uri RINGTONEURI_PROXY(RINGTONE_LIBRARY_PROXY_DATA_URI_TONE_FILES + "&user=" + 226 std::to_string(SystemSoundManagerUtils::GetCurrentUserId())); 227 auto resultSet = dataShareHelper->Query(RINGTONEURI_PROXY, queryPredicates, COLUMNS, &businessError); 228 int32_t errCode = businessError.GetCode(); 229 Security::AccessToken::AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID(); 230 int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenCaller, 231 "ohos.permission.ACCESS_CUSTOM_RINGTONE"); 232 MEDIA_LOGI("GetRingtoneAttrList:errCode:%{public}d, result :%{public}d ", errCode, result); 233 if (errCode != 0 || result != Security::AccessToken::PermissionState::PERMISSION_GRANTED || 234 !SystemSoundManagerUtils::GetScannerFirstParameter(RINGTONE_PARAMETER_SCANNER_FIRST_KEY, RINGTONEPARA_SIZE) || 235 !SystemSoundManagerUtils::CheckCurrentUser()) { 236 dataShareHelper = SystemSoundManagerUtils::CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); 237 CHECK_AND_RETURN_RET_LOG(dataShareHelper != nullptr, ringtoneAttrsArray_, 238 "Invalid dataShare, datashare or ringtone library error."); 239 resultSet = dataShareHelper->Query(RINGTONEURI, queryPredicates, COLUMNS, &businessError); 240 } 241 ``` 242 243### 标准振动与弱振动 244 针对手机铃声,提供不同的振动方式。不同铃声类型支持的振动方式规格如下: 245 - 预制铃声:支持同步振动与非同步振动 246 - 同步振动 247 示例:振动方式与铃声同步,预制铃声选择 "A",同步振动即为振动时直接使用"A"铃声所对应的标准或弱化振动方式。 248 - 非同步振动 249 示例:振动方式选中与铃声不同步,可选择振动列表中任何一个,比如:选择"B",即振动时使用"B"对应的标准或弱化振动方式 250 - 自定义铃声 251 - 非同步振动 252 示例:铃声选择本地音乐,比如铃声为"ringtone.ogg",选择振动列表中任何一个,比如选择"B",振动时使用"B"对应的标准或弱化振动方式。 253 254### RingtoneLibrary数据库表结构 255- 铃音表结构 256 257|字段名|类型|描述| 258|---|---|---| 259|ringtone_id|INTEGER|主键,数据库自增| 260|data|TEXT|铃音文件存储路径| 261|size|BITINT|铃音文件大小| 262|display_name|TEXT|title+后缀| 263|title|TEXT|铃音名称| 264|media_type|TEXT|媒体类型,音频类为2| 265|tone_type|INTEGER|ALARM = 0, RINGTONE = 1, NOTIFICATION = 2, NOTIFICATION可以设置为短信和通知| 266|mime_type|TEXT|UTI类型| 267|source_type|INTEGER|系统预制(1),用户自定义(2)| 268|date_added|BIGINT|时间戳,添加时间| 269|date_modified|BIGINT|时间戳,修改时间| 270|date_taken|BIGINT|时间戳,创建时间| 271|duration|INTEGER|时长,毫秒值| 272|shot_tone_type|INTEGER|短信铃音类型: 非短信音(0),卡1短信音(1),卡2短信音(2),双卡短信音(3)| 273|shot_tone_source_type|INTEGER|系统设置(1),用户设置(2)| 274|notification_tone_type|INTEGER|通知音铃音类型: 非通知音(0),通知音(1)| 275|notification_tone_source_type|INTEGER|系统设置(1),用户设置(2)| 276|ring_tone_type|INTEGER|通话铃音类型: 非通话铃音(0),卡1铃音(1),卡2铃音(2),双卡铃音(3)| 277|ring_tone_source_type|INTEGER|系统设置(1),用户设置(2)| 278|alarm_tone_type|INTEGER|闹钟铃音类型: 非闹钟铃音(0),闹钟铃音(1)| 279|alarm_tone_source_type|INTEGER|系统设置(1),用户设置(2)| 280 281- 振动表结构 282 283|字段名|类型|描述| 284|---|---|---| 285|vibrate_id|INTEGER|主键,数据库自增| 286|data|TEXT|振动文件存储路径| 287|size|BITINT|振动文件大小| 288|display_name|TEXT|title+后缀| 289|title|TEXT|振动名称| 290|vibrate_type|INTEGER|振动类型:经典标准(1), 经典弱化(2), 闹钟标准(3), 来电标准(4), 通知标准(5), 闹钟弱化(6), 来电弱化(7), 通知弱化(8)| 291|display_language|TEXT|title语言类型| 292|source_type|INTEGER|系统预制(1),用户自定义(2)| 293|date_added|BIGINT|时间戳,添加时间| 294|date_modified|BIGINT|时间戳,修改时间| 295|date_taken|BIGINT|时间戳,创建时间| 296|play_mode|INTEGER|播放模式:同步(1), 经典(2)| 297|scanner_flag|INTEGER|扫描标志位:默认为0,扫描过程中将其置1,扫描结束恢复为0| 298 299## 相关仓<a name="section1533973044317"></a> 300**[multimedia/ringtone_library](https://gitee.com/openharmony/multimedia_ringtone_library)** 301**[multimedia/player_framework](https://gitee.com/openharmony/multimedia_player_framework)** 302