更新记录

1.0.240905(2024-09-09)

  • 新增appNativePlugin_sampleRate原生插件录音选项,允许设置录音采样率
  • writeFile接口新增seekOffset选项,支持在文件指定位置覆盖写入数据
  • iOS新增ios_categoryResetPlayback_AEC原生插件录音选项,用于提高部分音频设备的兼容性
  • iOS重写打开录音逻辑,解决老版本打开录音小概率卡住的问题

1.0.240705(2024-07-05)

新增ios_categoryOptions原生插件录音选项,AVAudioSession的CategoryOptions默认值为 0x1|0x4 (MixWithOthers | AllowBluetooth),允许录音时其他app保持播放

1.0.240409(2024-04-10)

第一次发布

查看更多

平台兼容性

Android iOS
× 适用版本区间:9 - 17

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


Recorder原生录音插件:实时帧回调、文件流式读写

本原生插件提供Android、iOS双端支持(可单独购买),是前端组件 Recorder-UniCore 的配套插件,搭配使用时可以提供丰富的功能支持;或者直接调用本原生插件接口,不过能做到的功能有限。

推荐搭配Recorder-UniCore前端组件一起使用,可做到:

  • 支持已有的大部分录音格式:mp3、wav、pcm、amr、ogg、g711a、g711u等
  • 支持实时处理,包括变速变调、实时上传、ASR语音转文字
  • 支持可视化波形显示;可配置回声消除、降噪;注意:不支持通话时录音
  • 支持使用部分线控耳机、蓝牙耳机、USB外设的麦克风录音
  • 支持文件流式读写,录音数据可以实时写入到文件
  • 支持离线使用,前端组件和本原生插件均不依赖网络

详细文档(含Demo项目): https://github.com/xiangyuecn/Recorder/tree/master/app-support-sample/demo_UniApp

Recorder开源库地址: https://github.com/xiangyuecn/Recorder

如果github打不开,可以点此访问Gitee仓库地址

选择适用你的版本

本原生插件支持Android、iOS分开单独到DCloud插件市场购买,均包含了Recorder-UniCore前端组件的商用授权;你可以只购买授权,费用为 ¥199元 ,相当于同时赠送了Android版原生插件(如果用不着这个原生插件可以不使用即可)。

版本 价格 说明
授权+送Android ¥199 建议只购买授权、或只Android上使用时购买
单iOS+补差价 ¥399 只含iOS版原生插件,建议只iOS上使用时购买
Android+iOS ¥598 含Android、iOS原生插件

购买后可联系客服,同时提供订单信息,客服拉你进入VIP支持QQ群,在群文件中可下载Recorder-UniCore前端组件的app-uni-support.js文件最新源码;客服联系方式:QQ( 125 165 4593 ) ,或者直接联系作者QQ( 753 610 399 ) (回复可能没有客服及时)。

注:VIP支持群的主要作用是代表你已获得授权许可,可以随时获得app-uni-support.js文件最新版源码;不作为问答或售后群使用,当然如果你有问题也可以直接群里问,花费时间不多的,作者免费顺带就解答了,如果复杂花费比较久时间的,可能要适当收点人工费用,或者选择进行付费指导。

Recorder-UniCore组件中自带的app-uni-support.js文件是压缩版,功能和源码版一致,在VIP支持群中下载得到此文件源码后,可以直接替换组件中的这个文件,也可以不替换。

如何开票

插件市场付费购买插件支持开票(由DCloud开具),具体请参考 DCloud 云服务如何开具发票 ;在插件市场 我的插件 - 我使用的插件 - 购买的插件 可查看到购买的插件 和 开票相关指引。

测试方法

测试时无需购买插件,试用是免费的,并且原生插件试用是无限制的。

  1. 先到Recorder-UniCore下载示例项目(需根目录执行npm install完成recorder-core依赖的安装),在HBuilder中打开后,在项目manifest.json配置中分配一个uni-app应用标识
  2. 然后点击本插件页面中的试用按钮,在这个应用标识对应的项目中试用
  3. 然后在项目manifest.json的App原生插件配置中勾选本原生插件(注意:勾选了试用版时,购买后需要重新勾选成正式版)
  4. HBuilder中提交云打包打自定义基座
  5. 连接手机进行调试,使用自定义基座运行即可测试

录音权限配置

在uni-app项目的 manifest.json 中配置好Android和iOS的录音权限声明。

//Android需要勾选的权限,第二个也必须勾选
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
【注意】Android如果需要在后台录音,需要启用后台录音保活服务,请参考下面的`androidNotifyService`,否则锁屏或进入后台一段时间后App可能会被禁止访问麦克风导致录音静音、无法录音(renderjs中H5录音也受影响)

//iOS需要声明的权限
NSMicrophoneUsageDescription
【注意】iOS需要在 `App常用其它设置`->`后台运行能力`中提供`audio`配置,不然App切到后台后立马会停止录音

使用方法一:搭配Recorder-UniCore前端组件使用

插件集成

  1. 到插件市场下载安装Recorder-UniCore前端组件,并且项目根目录安装recorder-corenpm install recorder-core --registry=https://registry.npmmirror.com/
  2. 试用或购买本原生插件,在项目manifest.json的App原生插件配置中勾选本原生插件(注意:勾选了试用版时,购买后需要重新勾选成正式版)
  3. 参考上面的录音权限配置,在项目manifest.json中配置好权限
  4. 云打包自定义基座进行测试、或正式打包,即完成集成

调用录音

/** 集成好Recorder-UniCore组件后,直接调用RecordApp相关方法进行录音即可,详细请参考下面的demo_UniApp文档链接
    RecordApp.RequestPermission(...) 请求录音权限
    RecordApp.Start({ 开始录音
        type:"mp3",sampleRate:16000,bitRate:16
        //android_audioSource、ios_categoryOptions ... 原生插件支持的更多配置参数,请参考下面recordStart原生接口
    }, ...)
    RecordApp.Stop(...) 停止录音
    RecordApp.Pause() 暂停
    RecordApp.Resume() 继续
**/

//在调用RecordApp.RequestPermission之前进行配置,建议放到import后面直接配置(全局生效)
//也可以判断一下只在iOS上或Android上启用,不判断就都启用,比如判断iOS:RecordApp.UniIsApp()==2
RecordApp.UniNativeUtsPlugin={ nativePlugin:true }; 

//只需进行这个配置就行,在RecordApp录音时就会自动使用原生插件来录音;未启用原生插件时App内默认是在renderjs使用H5录音

//提升后台录音的稳定性:配置了原生插件后,可配置 `RecordApp.UniWithoutAppRenderjs=true` 禁用renderjs层音频编码(WebWorker加速),变成逻辑层中直接编码(但会降低逻辑层性能),后台运行时可避免部分手机WebView运行受限的影响
//提升后台录音的稳定性:需要启用后台录音保活服务(iOS不需要),详细请参考下面的`androidNotifyService`

手动调用原生插件接口

/**App中集成了原生插件后按下面代码进行调用,注意需要先配置RecordApp.UniNativeUtsPlugin
    参数:action 字符串,要调用的功能;args 对象,调用参数
    返回:any 根据功能定义返回对应的结果,出错会抛异常
比如将任意数据保存到文件:**/
try{
    var result=await RecordApp.UniNativeUtsPluginCallAsync("writeFile",{path:"test.txt", dataBase64:"dGVzdDEyMw=="});
}catch(e){
    console.error(e)
}

//更多可用接口请参考下面的《直接调用原生插件接口 - 可用的接口》

详细文档、RecordApp方法、属性文档

请先阅读 demo_UniApp文档,含Demo项目;更高级使用还需深入阅读 Recorder文档RecordApp文档 (均为完整的一个README.md文档),Recorder文档中包含了更丰富的示例代码:基础录音、实时处理、格式转码、音频分析、音频混音、音频生成 等等,大部分能在uniapp中直接使用。

使用方法二:直接调用原生插件接口

注意:仅使用原生插件接口来进行录音时,只支持返回pcm格式音频数据,不支持其他格式;pcm数据可以使用Recorder库进行转码成其他格式,或者直接使用Recorder-UniCore前端组件支持更多格式录音。

插件集成

  1. 试用或购买本原生插件,在项目manifest.json的App原生插件配置中勾选本原生插件(注意:勾选了试用版时,购买后需要重新勾选成正式版)
  2. 参考上面的录音权限配置,在项目manifest.json中配置好权限
  3. 云打包自定义基座进行测试、或正式打包,即完成集成

调用插件接口

//加载插件,注意:如果你使用的单独的Android或iOS版,请使用下面带后缀的
var RecNP=uni.requireNativePlugin("Recorder-NativePlugin");
//var RecNP=uni.requireNativePlugin("Recorder-NativePlugin-Android");
//var RecNP=uni.requireNativePlugin("Recorder-NativePlugin-iOS");

//调用插件接口,固定使用request方法进行调用
RecNP.request({
    action:"writeFile" //接口名称,这个例子是将任意数据保存到文件
    ,args:{path:"test.txt", dataBase64:"dGVzdDEyMw=="} //接口参数
},function(data){ //接口调用结果回调
    if(data.status!="success"){
        console.error(data.message); //调用错误处理
        return;
    };
    console.log(data.value); //接口调用结果
});

//绑定原生层回调
RecNP.request({action:"jsCall",args:{}},function(data){
    if(data.action=="onLog"){ //原生层日志输出
        var msg="[RecNP]["+data.tag+"]"+data.message;
        data.isError? console.error(msg) : console.log(msg);
    }else if(data.action=="onRecord"){ //录音pcm数据回调
        var sampleRate=data.sampleRate; //采样率
        var pcm=new Int16Array(uni.base64ToArrayBuffer(data.pcmDataBase64)); //16位pcm
        console.log("onRecord "+sampleRate+" "+pcm.length);
    }
});

//建议自行封装一个函数返回Promise来异步调用,方便好使
var RecNP_CallAsync=function(action,args){ return new Promise(function(resolve, reject){
    RecNP.request({ action:action,args:args||{} },function(data){
        if(data.status!="success"){
            reject(new Error(data.message));
            return;
        };
        resolve(data.value);
    });
}) };
//调用,这个例子是将任意数据保存到文件
try{
    var result=await RecNP_CallAsync("writeFile",{path:"test.txt", dataBase64:"dGVzdDEyMw=="});
}catch(e){
    console.error(e)
}

可用的接口

【文档说明】
下面的action中,开头的名字为RecNP.request的action,“参数”为args,“返回”为接口的返回值data.value

【录音相关action】 注意:在使用Recorder-UniCore组件时会自动调用这些接口,请勿自行调用
jsCall 【这是一个特殊方法】绑定原生层js回调,当原生层需要给js发送消息时,会进行回调(RecNP.request的回调方法会被反复调用)
    参数:{}
    返回:{ action:"", ... } //原生层会反复调用回调方法,通过其中的action来判断返回的是什么内容
        {action:"noop"} //无需处理,多次调用jsCall时原生层释放老的回调
        {action:"onLog",isError:false,tag:"xx",message:"xxx"} //原生层日志输出
        {action:"onRecord",sampleRate:44100,pcmDataBase64:"base64"} //录音数据回调,pcm为16位单声道,sampleRate是pcm的采样率

recordPermission 请求录音权限
    参数:{}
    返回:1 //权限状态code数值:1有权限,3用户拒绝。(2未用到;此接口早期移植的时候忘记改成对象,保留数值格式)

recordStart 开始录音,录音pcm数据会通过jsCall回调,开始后必须每5秒调用一次recordAlive;本方法会获取录音权限,但建议先调用recordPermission提前获取录音权限
    参数:{
        appNativePlugin_sampleRate:44100 //可选录制的采样率(24/09/05新增),默认返回44100采样率的pcm数据,可取值48000(在js中使用Recorder.SampleData函数来转换成需要的任意采样率);其他采样率值不一定可用,可能导致无法打开录音,请测试好后再提供
        ,appNativePlugin_AEC_Enable:false //可选是否启用回声消除,默认不启用

        ,android_audioSource:0 //可选Android指定麦克风源 MediaRecorder.AudioSource,默认值为0,0 DEFAULT 默认音频源,1 MIC 主麦克风,5 CAMCORDER 相机方向的麦,6 VOICE_RECOGNITION 语音识别,7 VOICE_COMMUNICATION 语音通信(带回声消除)。配置值除7外,会禁用回声消除

        ,ios_categoryOptions:0x1|0x4 //可选iOS的AVAudioSession setCategory的withOptions参数值,取值请下面的iosSetDefault_categoryOptions;默认值为5(0x1|0x4)
        ,ios_categoryResetPlayback_AEC:false //可选iOS打开录音时重置录音环境,用于提高部分音频设备的兼容性(24/09/05新增);iOS录音开启回声消除时,本原生插件可能无法感知到新插入的USB音频输入设备(如Lightning口/USB领夹麦克风),首次录音前插入的无此影响;可在录音时提供本true启用音频环境重置(默认false不重置),将能感知到所有音频输入设备,但会导致Start变慢;注意:录音中途新插入的USB设备可能任何配置下均无法感知到,需下次Start时才可以
    }
    返回:{} //空对象

recordStop 停止录音
    参数:{}
    返回:{} //空对象

recordAlive 定时心跳(开始录音后5秒发一次),如果超过10秒未发心跳,将会停止录音,防止未stop导致泄露
    参数:{}
    返回:{} //空对象

【其他可用action】
getInfo 获取插件信息
    参数:{}
    返回:{
        info:"" //插件信息字符串
        ,bundleId:"xx.xx.xx" //当前App包名,Android为Package值、iOS为Bundle ID值
        ,bundleIds:["allow all"] //插件打包包名列表,默认匹配任何包名
        ,distInfo:"standard" //插件打包信息,默认standard
    }

debugInfo 获取调试信息 (24/09/05新增)
    参数:{}
    返回:{ appMemoryUsage:123 } //app内存占用大小(不一定准),单位字节;数据来源:Android Debug.getMemoryInfo.TotalPss,iOS task_info.TASK_VM_INFO.phys

setSpeakerOff 切换扬声器外放和听筒播放,随时都可以调用;但需注意打开录音时可能会自动切换播放方式(24/09/05起打开录音默认off:false+headset:true),可在打开录音后调用一次切换成你需要的播放方式。iOS Bug:部分iOS系统版本首次切换或首次打开录音时,可能会导致已有的音频播放暂停但有播放进度变成假的无声,建议切换后或开始录音后再打开播放
    参数:{
        off:true //必填,true听筒播放,false扬声器播放,连接耳机时此配置无效
        headset:true //选填,默认true耳机播放,false扬声器播放(同时使用手机上的麦克风),连接耳机时此配置生效
        //配置场景:当由代码进行主动调用,比如开启回声消除录音时想播放的声音大点,就只提供off:false,这时没连接耳机会从扬声器播放,有耳机就从耳机播放
        //配置场景:当类似由用户点击外放按钮时调用,同时提供off:false+headset:false,这时不管有没有耳机,都会从扬声器播放
    }
    返回:{  } //空对象

iosSetDefault_categoryOptions iOS设置默认值,Android不可调用,为iOS的AVAudioSession setCategory的withOptions参数值;recordStart开始录音时如果未提供ios_categoryOptions参数,将会使用此默认值,提供了时将赋值给此默认值;setSpeakerOff调用时也会使用到此默认值
    参数:{
        value:0x1|0x4 //必填,取值(多选,默认值5=0x1|0x4):0 什么也不设置,0x1 MixWithOthers,0x2 DuckOthers,0x4 AllowBluetooth,0x8 DefaultToSpeaker(不可用,通过setSpeakerOff来切换),0x11 InterruptSpokenAudioAndMixWithOthers,0x20 AllowBluetoothA2DP,0x40 AllowAirPlay,0x80 OverrideMutedMicrophoneInterruption
    }
    返回:{  } //空对象

writeFile 数据写入文件,可新建文件、追加写入(文件流写入)
    参数:{
        path:"文件路径" //必填,支持的路径请参考下面
        ,dataBase64:"base64" //必填,写入的任意内容base64编码,可以为空字符串(如仅新建文件)
        ,append:false //可选,是否追加写入到文件结尾,默认false会新建文件并写入数据
        ,seekOffset:-1 //可选,从现有文件指定位置写入并覆盖对应内容(24/09/05新增),取值:-1不指定(默认),0 到 文件长度(0为文件开头位置,append配置无效)
    }
    返回:{
        fullPath:"/文件绝对路径"
    }

readFile 读取文件,可流式读取
    参数:{
        path:"文件路径" //必填,支持的路径请参考下面
        ,type:"base64" //可选,返回结果类型,默认base64,设为text时将读取成utf-8文本,提供了chunkSize时只支持base64
        ,chunkSize:0 //可选,本次读取的最大长度,单位字节,默认0读取全部
        ,chunkOffset:0 //可选,提供了chunkSize时,指定读取的开始位置
    }
    返回:{
        data:"文本或base64" //文件内容,类型取决于提供的type
        ,isExists:true //文件是否存在;文件不存在时不会返回错误,此时的data为空字符串
        ,totalSize:0 //文件大小
        ,fullPath:"/文件绝对路径"
    }

deleteFile 删除文件或文件夹
    参数:{
        path:"文件路径" //必填,支持的路径请参考下面(文件不存在时不会报错)
        ,isDir:false //可选,true时此路径是文件夹,删除此文件夹,默认false
    }
    返回:{ fullPath:"/文件绝对路径" }

moveFile 移动或重命名文件
    参数:{
        fromPath:"源文件路径" //必填,支持的路径请参考下面
        ,path:"新文件路径" //必填,如果存在会覆盖
    }
    返回:{ fullPath:"/移动后的文件绝对路径" }

copyFile 复制文件
    参数:{
        fromPath:"源文件路径" //必填,支持的路径请参考下面
        ,path:"新文件路径" //必填,如果存在会覆盖
    }
    返回:{ fullPath:"/复制后的文件绝对路径" }

resolvePath 解析路径成绝对路径
    参数:{
        path:"文件或文件夹路径" //必填(空字符串时为store目录),支持的路径请参考下面
        ,pathInfo:false //可选,是否返回路径信息,默认false不返回
    }
    返回:{
        fullPath:"/文件绝对路径"
        ,pathInfo:{ //可选返回路径信息
            isExists:true //文件或文件夹是否存在
            ,isFile:true //true时path为文件,false时为文件夹
            ,size:123 //isFile时文件大小,文件夹为0
            ,date:123456 //isFile时文件更新时间,毫秒,文件夹为0
        }
    }

listPath 读取文件夹内的文件
    参数:{ path:"文件夹路径" } //必填(空字符串时为store目录),支持的路径请参考下面
    返回:{
        files:[ { //此文件夹下的文件
                name:"文件名"
                ,size:123 //文件大小
                ,date:123456 //文件更新时间,毫秒
            } ]
        ,dirs:[ "文件夹名" ] //此文件夹下的文件夹
        ,fullPath:"/文件夹绝对路径" //结尾不带/
    }

androidNotifyService 搭配常驻通知的Android后台录音保活服务(24/09/05新增),iOS不可调用。注意:需要在项目根目录提供AndroidManifest.xml配置才可调用本接口,调用时App必须在前台(适配Android 12+),需要先调用请求录音权限后才能开启服务(适配Android 14+),详细请参考下面的“Android后台录音保活”
    参数:{
        title:"录音通知标题" //打开服务时必填,close为true时无需提供
        ,content:"录音通知内容" //可选,close为true时无需提供
        ,close:false //设为true时关闭服务和通知,不管打开服务是否成功,都需要调用close关闭
    }
    返回:{ } //close时返回空对象
    返回:{ //非close时只要成功返回结果,就代表服务已在运行,但通知可能不显示或会延迟显示,并不影响服务运行
        notifyPermissionCode:1 //仅供参考,通知的显示权限状态,取值:1有通知权限,3不确定,当App的targetSdkVersion>=33(Android 13+)时代表无通知权限,小于33时可能系统设置中未打开App的通知或正在弹框询问是否允许通知
        ,notifyPermissionMsg:"" //仅供参考,权限code对应的消息,当App的targetSdkVersion>=33时为:`(已|未)获得App的通知权限`,小于33时为:`系统设置中App的通知(已|未)打开`
    }

androidStoragePermission__limited 简易获取Android的外部存储权限,iOS不可调用,当你需要读写当前应用数据以外的文件时(如手机的Download目录文件),需要先获取外部存储权限;注意这个只会请求WRITE_EXTERNAL_STORAGE权限,因此TargetSDK需小于33(Android 13),否则此权限永远是拒绝的(请自行用别的途径获取权限)
    参数:{}
    返回:{ code:1 } //权限状态:1有权限,3用户拒绝。(2未用到)

【支持的路径】
"store://文件夹/文件.png" 或 "文件夹/文件.png" (开头不带/)
    app内部保存文件,文件夹是可选的
        Android为app的file目录 + 文件夹/文件.png
        iOS为app的Library/Files目录 + 文件夹/文件.png

"__doc://文件夹/文件.png"
    app内部保存文件,文件夹是可选的;兼容iOS Documents目录专用的,正常用"store://"就够了
        Android为app的file/__doc目录 + 文件夹/文件.png
        iOS为app的Documents目录 + 文件夹/文件.png

"cache://文件夹/文件.png"
    app内部缓存文件,文件夹是可选的,存储的文件可能会被用户或系统删除
        Android为app的cache目录 + 文件夹/文件.png
        iOS为app的Library/Caches目录 + 文件夹/文件.png

"file:///绝对路径/文件.png" 或 "/绝对路径/文件.png" (开头有/)
    绝对路径,一般只允许读写app自己目录内的文件;Android获取到了外部存储权限时(调用androidStoragePermission__limited),可能可以可读写外部存储中的文件;iOS不支持读写非app自己目录文件

Android后台录音保活

Android 9开始,为了保护用户隐私,锁屏或进入后台一段时间后App可能会被禁止访问麦克风、摄像头等功能,导致无法录音、或录音数据全部是静音,因此需要使用保活机制才能在后台录音;H5录音、原生接口录音均受影响。iOS不存在此类问题,iOS只要在manifest.json的后台运行能力中提供audio配置,即可在后台录音。

本插件已提供androidNotifyService接口,来控制搭配常驻通知的Android后台录音保活服务,打开服务后可提升App在后台或锁屏后录音的稳定性,注意:不同机型的录音保活效果不一定100%有效;此服务为前台服务(Foreground services),在启动的时候会在状态栏显示一个常驻的通知(通知可能不显示或会延迟显示,并不影响服务运行)。

【注意】targetSdkVersion>=31(Android 12+)时,App必须在前台才能调用此服务接口,在后台时不允许调用;targetSdkVersion>=34(Android 14+)时,microphone类型的服务依赖录音权限,因此建议先请求录音权限(调用RecordApp.RequestPermission、或recordPermission接口),成功后再来调用androidNotifyService接口。

【注意】使用前台服务后,在上架时可能需要声明需要使用的任何前台服务类型、提供使用说明和具体用例,否则可能导致部分应用市场无法上架;为了不影响不使用此服务的App,要使用本服务前要在AndroidManifest.xml中进行配置后才能使用

//请在项目根目录新建AndroidManifest.xml文件,填入以下内容(修改后需要重新打包才会生效)
//文档篇幅有限,下面内容的原文在demo项目的同名文件中,可在demo中找到此文件,或到github查看:https://github.com/xiangyuecn/Recorder/blob/master/app-support-sample/demo_UniApp/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 
    package="io.dcloud.nativeresouce">

    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"/>

    <application>
        <service
            android:name="uni.plugin.recorder.RecorderNativePlugin$RecNotifyService"
            android:foregroundServiceType="microphone"
            android:exported="false">
        </service>
    </application>
</manifest>

//上面这段代码仅用于Android后台录音保活服务,如果项目不需要后台录音保活,可以不复制
//iOS只要在manifest.json的`后台运行能力`中提供`audio`配置,即可在后台录音

隐私、权限声明

1. 本插件需要申请的系统权限列表:

录音权限

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问