怎样在HarmonyOS中调用百度翻译API

农民  金牌会员 | 2024-12-24 04:19:43 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 820|帖子 820|积分 2460

先容

通过http哀求和HarmonyOS自带的加密框架,可以为移动应用实现调用百度翻译API的功能。

开辟环境要求
 • DevEco Studio版本:DevEco Studio 3.1 Release
 • HarmonyOS SDK版本:API version 9
工程要求
 • API9
 • Stage模子


正文

代码布局
  1. main
  2. ├─ module.json5
  3. ├─ resources
  4. │  ├─ zh_CN
  5. │  ├─ rawfile        //图片资源目录
  6. │  │  ├─ image1.png
  7. │  │  └─ image2.png
  8. │  └─ base
  9. └─ ets
  10.    ├─ XL_Modules
  11.    │  └─ XL_Translation_Tool.ts    //翻译工具模块
  12.    ├─ pages
  13.    │  └─ Index.ets          //主页面
  14.    └─ entryability
  15.       └─ EntryAbility.ts
复制代码

添加权限
在本案例中,我们是通过http数据哀求的方式调用百度翻译API的,这意味着应用必须拥有联网权限。所以我们必要在module.json5中申请“name”为"ohos.permission.INTERNET"的权限
  1. {
  2.   "module": {
  3.     "name": "entry",
  4.     "type": "entry",
  5.     "description": "$string:module_desc",
  6.     "mainElement": "EntryAbility",
  7.     "deviceTypes": [
  8.       "phone"
  9.     ],
  10.     "deliveryWithInstall": true,
  11.     "installationFree": false,
  12.     "pages": "$profile:main_pages",
  13.     "requestPermissions": [
  14.       {
  15.         "name": "ohos.permission.INTERNET",
  16.         "usedScene": {
  17.           "abilities": [
  18.             "EntryAbility"
  19.           ],
  20.           "when": "inuse"
  21.         }
  22.       }
  23.     ],
  24.     "abilities": [
  25.       {
  26.         "name": "EntryAbility",
  27.         "srcEntry": "./ets/entryability/EntryAbility.ts",
  28.         "description": "$string:EntryAbility_desc",
  29.         "icon": "$media:icon",
  30.         "label": "$string:EntryAbility_label",
  31.         "startWindowIcon": "$media:icon",
  32.         "startWindowBackground": "$color:start_window_background",
  33.         "exported": true,
  34.         "skills": [
  35.           {
  36.             "entities": [
  37.               "entity.system.home"
  38.             ],
  39.             "actions": [
  40.               "action.system.home"
  41.             ]
  42.           }
  43.         ]
  44.       }
  45.     ]
  46.   }
  47. }
复制代码
获取百度翻译开放平台的App Id和密钥

开辟者能通过http数据哀求调用百度翻译API的前提是提供一些必要的认证信息,即开辟者在百度翻译开放平台的App Id与密钥。
首先,进入百度翻译开放平台的网址,网页链接为http://api.fanyi.baidu.com。随后,注册个人用户,并在注册完成之后打开开辟者信息的选项,即可查看本身的App Id与密钥。

末了,我们还必要在平台中开通通用文本翻译API(这个是免费申请的),成功开通后可以进入下一步



翻译工具模块
在本案例中,调用百度翻译API的关键代码被封装在翻译工具类中,而翻译工具类( XL_Translation_Tool)则被集成在文件 XL_Translation_Tool.ts中。
在XL_Translation_Tool.ts中,首先必要导入cryptoFramework与http,前者用于MD5数据加密,后者用于http数据哀求。接着编写两个辅助函数,分别为Generate_number_Sequence_10与Transform_10_To_16,前者用于生成十位随机数,后者则用于将10进制整数序列转换为16进制整数序列。随后,将MD5加密的代码封装在异步函数Generate_Sign内,并创建类XL_Translation_Tool。
在类XL_Translation_Tool中,provideDeveloperInfo方法用于获取开辟者在百度翻译开放平台的App Id与密钥,translate方法则是基于上述App Id与密钥,以及待翻译文本,来调用百度翻译API。
调用API必要的URL格式如下


末了,导出一个XL_Translation_Tool实例
  1. //导入加密框架
  2. import cryptoFramework from '@ohos.security.cryptoFramework';
  3. //导入http模块
  4. import http from '@ohos.net.http';
  5. /*
  6.  * 函数名: Generate_number_Sequence_10
  7.  * 描述: 随机生成携带十个元素的数字序列(此序列的数据类型为字符串)
  8.  */
  9. function Generate_number_Sequence_10():string{
  10.   var ret:string = ''
  11.   for(var i = 0; i < 10; ++i){
  12.     ret += Math.floor(Math.random()*9.999)
  13.   }
  14.   console.info('------[Random] '+ret)
  15.   return ret
  16. }
  17. /*
  18.  * 函数名: Transform_10_To_16
  19.  * 描述: 用于将10进制整数序列(参数的数据类型为Uint8Array)转换为16进制整数序列(输出的数据类型为字符串)的辅助函数
  20.  */
  21. function Transform_10_To_16(Sign_10:Uint8Array):string{
  22.   let Array_16 = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
  23.   let Sign_16:string = ''
  24.   for(var item of Sign_10) Sign_16 += Array_16[(item-item%16)/16]+Array_16[item%16]
  25.   console.info('------[MD5 16]: '+Sign_16.toString())
  26.   return Sign_16
  27. }
  28. /*
  29.  * 函数名: Generate_Sign
  30.  * 描述: 通过MD5模块进行信息加密, 以生成签名
  31.  */
  32. async function Generate_Sign(query:string,appId:string, key:string, sequence_10:string){
  33.   //预定义输出
  34.   let output = {
  35.     'ifComplete':false,
  36.     'Sign_16':null,
  37.   }
  38.   //创建md模块
  39.   let MD5 = cryptoFramework.createMd('MD5')
  40.   //MD5加密的输入值
  41.   let sign = appId + query + sequence_10 + key
  42.   //数据转换
  43.   var arr = []
  44.   for(var i = 0 ; i < sign.length ; i++)arr.push(sign.charCodeAt(i))
  45.   var dataBlog = {
  46.     data:new Uint8Array(arr)
  47.   }
  48.   console.info('------[MD5 10] dataBlog: '+dataBlog.data.toString())
  49.   //开始MD5加密
  50.   await MD5.update(dataBlog)
  51.   var SecretSign
  52.   await MD5.digest().then((mdOutput) => {
  53.     SecretSign = mdOutput.data
  54.     console.info("------[MD5 10] MD result: " + SecretSign.toString());
  55.     output.ifComplete = true
  56.     output.Sign_16 = SecretSign
  57.   }).catch((err) => console.error("------[MD5 10] err: " + err.code))
  58.   output.Sign_16 = Transform_10_To_16(SecretSign)
  59.   //输出加密结果
  60.   return output
  61. }
  62. /*
  63.  * 枚举名: TranslationForm
  64.  * 描述: 用于确定翻译流程的始末
  65.  */
  66. export enum TranslationForm{
  67.   From_En_To_Zh = 0,
  68.   From_Zh_To_En = 1
  69. }
  70. /*
  71.  * 数据类型名: TranslationResult
  72.  * 描述: 类XL_Translation_Tool的translate方法返回的数据类型
  73.  */
  74. declare type TranslationResult = {
  75.   ifComplete:boolean
  76.   result:string
  77.   description:string
  78. }
  79. class XL_Translation_Tool{
  80.   private TAG:string = '------[XL_Translation_Tool] '
  81.   private Baidu_Translation_API_URL_Prefix:string = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
  82.   private Baidu_APPID:string = ''
  83.   private Baidu_Key:string = ''
  84.   private If_Provide_Developer_Info:boolean = false
  85.   /*
  86.    * 方法名: provideDeveloperInfo
  87.    * 描述: 为XL_Translation_Tool提供百度翻译平台的开发者信息, 这是百度翻译API得以被调用的前提
  88.    */
  89.   public provideDeveloperInfo(appId:string, key:string){
  90.     this.Baidu_APPID = appId
  91.     this.Baidu_Key = key
  92.     this.If_Provide_Developer_Info = true
  93.   }
  94.   /*
  95.    * 方法名: translate
  96.    * 描述: 将输入的字符串信息, 通过百调用度翻译API进行翻译并返回
  97.    */
  98.   public async translate(message:string, form:TranslationForm):Promise<TranslationResult>{
  99.     //预定义返回值
  100.     var ret:TranslationResult = {
  101.       ifComplete:false,
  102.       result:null,
  103.       description:''
  104.     }
  105.     //判断appId和key是否被提供
  106.     if(!this.If_Provide_Developer_Info){
  107.       ret.description = '请为翻译工具提供百度智能翻译平台的开发者信息'
  108.       console.info(this.TAG+'Please provide the appId and key')
  109.       return ret
  110.     }
  111.     //通过http模块实例化HttpRequest
  112.     var httpRequest = http.createHttp()
  113.     let from:string
  114.     let to:string
  115.     let query:string = message+''
  116.     if(form == TranslationForm.From_En_To_Zh){
  117.       from = 'en'
  118.       to = 'zh'
  119.     }else if(form == TranslationForm.From_Zh_To_En){
  120.       from = 'zh'
  121.       to = 'en'
  122.     }
  123.     //生成10位随机整数序列
  124.     const RANDOM_SEQUENCE:string = Generate_number_Sequence_10()
  125.     var sign:string
  126.     //生成签名
  127.     let msg = await Generate_Sign(query,this.Baidu_APPID,this.Baidu_Key,RANDOM_SEQUENCE)
  128.     if(msg.ifComplete){
  129.       sign = msg.Sign_16
  130.     }else {
  131.       ret.description = '加密过程出错, 请检查相关项'
  132.       return ret
  133.     }
  134.     //拼接URL
  135.     let url = this.Baidu_Translation_API_URL_Prefix
  136.     +'?q=' + encodeURI(query)
  137.     +'&from=' +from
  138.     +'&to='+to
  139.     +'&appid='+this.Baidu_APPID
  140.     +'&salt='+RANDOM_SEQUENCE
  141.     +'&sign='+sign
  142.     console.info(this.TAG+'url: '+url)
  143.     //调用request方法
  144.     await httpRequest.request(url,{
  145.       method:http.RequestMethod.POST,
  146.       header:{
  147.         'Content-Type': 'application/x-www-form-urlencoded'
  148.       }
  149.     }).then((data)=>{
  150.       console.info(this.TAG+'Succeed in connecting to Internet')
  151.       // @ts-ignore
  152.       let trans_result = JSON.parse(data.result).trans_result
  153.       console.info(this.TAG+'Result:' + data.result);
  154.       console.info(this.TAG+'code:' + JSON.stringify(data.responseCode));
  155.       console.info(this.TAG+'Translate output:'+trans_result[0].dst)
  156.       ret.ifComplete = true
  157.       ret.description = '翻译成功'
  158.       ret.result = trans_result[0].dst
  159.     }).catch(err => console.error(this.TAG+'err:'+JSON.stringify(err)))
  160.     //销毁HttpRequest实例
  161.     httpRequest.destroy()
  162.     //返回翻译结果
  163.     return ret
  164.   }
  165. }
  166. //导出本模块
  167. export default new XL_Translation_Tool()
复制代码
主页面

在页面Index.ets中,我们必要计划一个自定义弹窗(名为dialog1)。该弹窗有一个用@Link装饰器修饰的变量If_Provide_Developer_Info,表现此自定义弹窗组件与其父组件支持双向数据通报。弹窗中有两个文本输入组件,分别用于输入开辟者的App Id与密钥,而内容为"确定"的文本组件则用于调用XL_Translation_Tool实例的provideDeveloperInfo方法,将开辟者认证信息载入XL_Translation_Tool实例中。
  1. //导入自定义的翻译工具
  2. import XL_Translation_Tool, { TranslationForm } from 'ets/XL_Modules/XL_Translation_Tool'
  3. //主页面UI
  4. @Entry
  5. @Component
  6. struct Index{
  7.   ......
  8. }
  9. //自定义弹窗
  10. @CustomDialog
  11. struct dialog1{
  12.   dialogController:CustomDialogController
  13.   @Link If_Provide_Developer_Info:boolean
  14.   @State private Baidu_AppId:string = ''
  15.   @State private Baidu_Key:string = ''
  16.   build(){
  17.     Column(){
  18.       Text('APP Id: ')
  19.         .fontSize(20)
  20.         .fontWeight(600)
  21.         .fontColor(Color.Gray)
  22.         .margin({
  23.           top:20,
  24.           bottom:4
  25.         })
  26.         .width('86%')
  27.       TextInput()
  28.         .type(InputType.Number)
  29.         .width('95%')
  30.         .height(40)
  31.         .backgroundColor('#eeeeee')
  32.         .onChange((value:string) => this.Baidu_AppId = value)
  33.       Text('密钥: ')
  34.         .fontSize(20)
  35.         .fontWeight(600)
  36.         .fontColor(Color.Gray)
  37.         .margin({
  38.           top:20,
  39.           bottom:4
  40.         })
  41.         .width('86%')
  42.       TextInput({
  43.         text:this.Baidu_Key
  44.       })
  45.         .type(InputType.Password)
  46.         .width('95%')
  47.         .height(40)
  48.         .backgroundColor('#eeeeee')
  49.         .onChange((value:string) => this.Baidu_Key = value)
  50.       Row(){
  51.         Text('确认')
  52.           .fontSize(24)
  53.           .fontWeight(700)
  54.           .fontColor(Color.Blue)
  55.           .onClick(() => {
  56.             this.dialogController.close()
  57.             this.If_Provide_Developer_Info = true
  58.             XL_Translation_Tool.provideDeveloperInfo(this.Baidu_AppId, this.Baidu_Key)
  59.           })
  60.         Text('取消')
  61.           .fontSize(24)
  62.           .fontWeight(700)
  63.           .fontColor(Color.Red)
  64.           .onClick(() => {
  65.             this.dialogController.close()
  66.           })
  67.       }
  68.       .width('100%')
  69.       .margin({
  70.         top:30
  71.       })
  72.       .justifyContent(FlexAlign.SpaceEvenly)
  73.     }
  74.     .height(260)
  75.     .width('92%')
  76.   }
  77. }
复制代码
末了,编写页面入口Index。dialogController表现自定义弹窗组件dialog1的控制器。
  1. //导入自定义的翻译工具
  2. import XL_Translation_Tool, { TranslationForm } from 'ets/XL_Modules/XL_Translation_Tool'
  3. //主页面UI
  4. @Entry
  5. @Component
  6. struct Index {
  7.   @State private If_Provide_Developer_Info:boolean = false
  8.   @State private translation_mode:number = TranslationForm.From_En_To_Zh
  9.   @State private translation_content:string = ''
  10.   @State private translation_result:string = ''
  11.   private dialogController = new CustomDialogController({
  12.     builder:dialog1({
  13.       If_Provide_Developer_Info:$If_Provide_Developer_Info
  14.     })
  15.   })
  16.   private async Begin_Translate(){
  17.     let result = await XL_Translation_Tool.translate(this.translation_content, this.translation_mode)
  18.     this.translation_result = result.result
  19.   }
  20.   build() {
  21.       Column() {
  22.         Text('百度翻译API')
  23.           .fontSize(36)
  24.           .fontColor(Color.Pink)
  25.           .fontWeight(800)
  26.           .margin({
  27.             top:20
  28.           })
  29.         Row(){
  30.           Row() {
  31.             Text('英译中')
  32.               .fontSize(20)
  33.               .fontColor('#8099ff')
  34.               .fontWeight(800)
  35.             Image($rawfile('image2.png'))
  36.               .height(30)
  37.               .width(30)
  38.           }
  39.           Text('提供密钥')
  40.             .fontSize(20)
  41.             .fontColor('#ff6666')
  42.             .fontWeight(800)
  43.             .onClick(() => this.dialogController.open())
  44.         }
  45.         .margin({
  46.           top:20
  47.         })
  48.         .width('100%')
  49.         .justifyContent(FlexAlign.SpaceEvenly)
  50.         Text('输入')
  51.           .fontSize(20)
  52.           .fontWeight(600)
  53.           .fontColor(Color.Gray)
  54.           .margin({
  55.             top:30,
  56.             bottom:10
  57.           })
  58.           .width('86%')
  59.         TextArea()
  60.           .width('90%')
  61.           .height(120)
  62.           .border({
  63.             width:3,
  64.           })
  65.           .onChange((value:string) => this.translation_content = value)
  66.           .fontSize(21)
  67.         Text() {
  68.           Span('结果')
  69.         }
  70.         .fontSize(20)
  71.         .fontWeight(600)
  72.         .fontColor(Color.Gray)
  73.         .margin({
  74.           top: 30,
  75.           bottom: 10
  76.         })
  77.         .width('86%')
  78.         TextArea({
  79.           text:this.translation_result
  80.         })
  81.           .width('90%')
  82.           .height(150)
  83.           .border({
  84.             width:3,
  85.           })
  86.         .fontSize(21)
  87.         Row(){
  88.           Image($rawfile('image1.png'))
  89.             .height(40)
  90.             .width(40)
  91.           Text('翻译')
  92.             .fontWeight(700)
  93.             .fontSize(24)
  94.             .fontColor(Color.White)
  95.             .margin({
  96.               left:20
  97.             })
  98.         }
  99.         .width('93%')
  100.         .height(50)
  101.         .backgroundColor('#8099ff')
  102.         .borderRadius(30)
  103.         .justifyContent(FlexAlign.Center)
  104.         .margin({
  105.           top:50
  106.         })
  107.         .onClick(() =>{
  108.           if(!this.If_Provide_Developer_Info){
  109.             this.dialogController.open()
  110.             return
  111.           }
  112.           console.info('------[ArkUI] '+'--'+this.translation_content+'--')
  113.           this.Begin_Translate()
  114.         })
  115.       }
  116.       .width('100%')
  117.   }
  118. }
  119. //自定义弹窗
  120. @CustomDialog
  121. ......
复制代码
如许之后,调用百度API的案例便编写完成了,使用模拟器或真机可以查看运行效果。受一些奇怪的bug的影响,本案例中的翻译功能只支持英译中。
总结

通过本次案例,信赖你已经学会怎样在HarmonyOS中调用百度翻译API。
末了

假如你想快速提拔鸿蒙技术,那么可以直接领取这份包含了:【OpenHarmony多媒体技术、Stage模子、ArkUI多端部署、分布式应用开辟、音频、视频、WebGL、Napi组件、OpenHarmony内核、Harmony南向开辟、鸿蒙项目实战】等技术知识点。
鸿蒙Next全套VIP学习资料←点击领取!(安全链接,放心点击
1.鸿蒙核心技术学习门路


2.大厂口试必问口试题


3.鸿蒙南向开辟技术


 4.鸿蒙APP开辟必备


 5.HarmonyOS Next 最新全套视频教程


 6.鸿蒙生态应用开辟白皮书V2.0PDF


这份全套完备版的学习资料已经全部打包好,朋友们假如必要可以点击鸿蒙Next全套VIP学习资料免费领取(安全链接,放心点击


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农民

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表