HarmonyOS开发移动应用:调用百度翻译开放平台的App Id和密钥

news2024/11/15 7:52:24

 介绍

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

开发环境要求

 • DevEco Studio版本:DevEco Studio 3.1 Release

 • HarmonyOS SDK版本:API version 9

工程要求

 • API9

 • Stage模型

图片

正文

代码结构

main
├─ module.json5
├─ resources
│  ├─ zh_CN
│  ├─ rawfile        //图片资源目录
│  │  ├─ image1.png
│  │  └─ image2.png
│  └─ base
└─ ets
   ├─ XL_Modules
   │  └─ XL_Translation_Tool.ts    //翻译工具模块
   ├─ pages
   │  └─ Index.ets          //主页面
   └─ entryability
      └─ EntryAbility.ts

添加权限

在本案例中,我们是通过http数据请求的方式调用百度翻译API的,这意味着应用必须拥有联网权限。所以我们需要在module.json5中申请“name”为"ohos.permission.INTERNET"的权限

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      }
    ],
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ts",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ]
  }
}

获取百度翻译开放平台的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实例

//导入加密框架
import cryptoFramework from '@ohos.security.cryptoFramework';

//导入http模块
import http from '@ohos.net.http';

/*
 * 函数名: Generate_number_Sequence_10
 * 描述: 随机生成携带十个元素的数字序列(此序列的数据类型为字符串)
 */
function Generate_number_Sequence_10():string{

  var ret:string = ''

  for(var i = 0; i < 10; ++i){
    ret += Math.floor(Math.random()*9.999)
  }

  console.info('------[Random] '+ret)
  return ret

}

/*
 * 函数名: Transform_10_To_16
 * 描述: 用于将10进制整数序列(参数的数据类型为Uint8Array)转换为16进制整数序列(输出的数据类型为字符串)的辅助函数
 */
function Transform_10_To_16(Sign_10:Uint8Array):string{
  let Array_16 = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
  let Sign_16:string = ''
  for(var item of Sign_10) Sign_16 += Array_16[(item-item%16)/16]+Array_16[item%16]
  console.info('------[MD5 16]: '+Sign_16.toString())
  return Sign_16
}

/*
 * 函数名: Generate_Sign
 * 描述: 通过MD5模块进行信息加密, 以生成签名
 */
async function Generate_Sign(query:string,appId:string, key:string, sequence_10:string){

  //预定义输出
  let output = {
    'ifComplete':false,
    'Sign_16':null,
  }

  //创建md模块
  let MD5 = cryptoFramework.createMd('MD5')

  //MD5加密的输入值
  let sign = appId + query + sequence_10 + key

  //数据转换
  var arr = []
  for(var i = 0 ; i < sign.length ; i++)arr.push(sign.charCodeAt(i))
  var dataBlog = {
    data:new Uint8Array(arr)
  }
  console.info('------[MD5 10] dataBlog: '+dataBlog.data.toString())

  //开始MD5加密
  await MD5.update(dataBlog)
  var SecretSign
  await MD5.digest().then((mdOutput) => {
    SecretSign = mdOutput.data
    console.info("------[MD5 10] MD result: " + SecretSign.toString());
    output.ifComplete = true
    output.Sign_16 = SecretSign
  }).catch((err) => console.error("------[MD5 10] err: " + err.code))

  output.Sign_16 = Transform_10_To_16(SecretSign)

  //输出加密结果
  return output

}

/*
 * 枚举名: TranslationForm
 * 描述: 用于确定翻译流程的始末
 */
export enum TranslationForm{

  From_En_To_Zh = 0,

  From_Zh_To_En = 1

}

/*
 * 数据类型名: TranslationResult
 * 描述: 类XL_Translation_Tool的translate方法返回的数据类型
 */
declare type TranslationResult = {

  ifComplete:boolean

  result:string

  description:string

}

class XL_Translation_Tool{

  private TAG:string = '------[XL_Translation_Tool] '

  private Baidu_Translation_API_URL_Prefix:string = 'https://fanyi-api.baidu.com/api/trans/vip/translate'

  private Baidu_APPID:string = ''

  private Baidu_Key:string = ''

  private If_Provide_Developer_Info:boolean = false

  /*
   * 方法名: provideDeveloperInfo
   * 描述: 为XL_Translation_Tool提供百度翻译平台的开发者信息, 这是百度翻译API得以被调用的前提
   */
  public provideDeveloperInfo(appId:string, key:string){
    this.Baidu_APPID = appId
    this.Baidu_Key = key
    this.If_Provide_Developer_Info = true
  }

  /*
   * 方法名: translate
   * 描述: 将输入的字符串信息, 通过百调用度翻译API进行翻译并返回
   */
  public async translate(message:string, form:TranslationForm):Promise<TranslationResult>{

    //预定义返回值
    var ret:TranslationResult = {
      ifComplete:false,
      result:null,
      description:''
    }

    //判断appId和key是否被提供
    if(!this.If_Provide_Developer_Info){
      ret.description = '请为翻译工具提供百度智能翻译平台的开发者信息'
      console.info(this.TAG+'Please provide the appId and key')
      return ret
    }

    //通过http模块实例化HttpRequest
    var httpRequest = http.createHttp()

    let from:string
    let to:string
    let query:string = message+''

    if(form == TranslationForm.From_En_To_Zh){
      from = 'en'
      to = 'zh'
    }else if(form == TranslationForm.From_Zh_To_En){
      from = 'zh'
      to = 'en'
    }

    //生成10位随机整数序列
    const RANDOM_SEQUENCE:string = Generate_number_Sequence_10()

    var sign:string

    //生成签名
    let msg = await Generate_Sign(query,this.Baidu_APPID,this.Baidu_Key,RANDOM_SEQUENCE)
    if(msg.ifComplete){
      sign = msg.Sign_16
    }else {
      ret.description = '加密过程出错, 请检查相关项'
      return ret
    }

    //拼接URL
    let url = this.Baidu_Translation_API_URL_Prefix
    +'?q=' + encodeURI(query)
    +'&from=' +from
    +'&to='+to
    +'&appid='+this.Baidu_APPID
    +'&salt='+RANDOM_SEQUENCE
    +'&sign='+sign

    console.info(this.TAG+'url: '+url)

    //调用request方法
    await httpRequest.request(url,{
      method:http.RequestMethod.POST,
      header:{
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }).then((data)=>{
      console.info(this.TAG+'Succeed in connecting to Internet')
      // @ts-ignore
      let trans_result = JSON.parse(data.result).trans_result
      console.info(this.TAG+'Result:' + data.result);
      console.info(this.TAG+'code:' + JSON.stringify(data.responseCode));
      console.info(this.TAG+'Translate output:'+trans_result[0].dst)
      ret.ifComplete = true
      ret.description = '翻译成功'
      ret.result = trans_result[0].dst
    }).catch(err => console.error(this.TAG+'err:'+JSON.stringify(err)))

    //销毁HttpRequest实例
    httpRequest.destroy()

    //返回翻译结果
    return ret
  }

}

//导出本模块
export default new XL_Translation_Tool()

主页面

在页面Index.ets中,我们需要设计一个自定义弹窗(名为dialog1)。该弹窗有一个用@Link装饰器修饰的变量If_Provide_Developer_Info,表示此自定义弹窗组件与其父组件支持双向数据传递。弹窗中有两个文本输入组件,分别用于输入开发者的App Id与密钥,而内容为"确定"的文本组件则用于调用XL_Translation_Tool实例的provideDeveloperInfo方法,将开发者认证信息载入XL_Translation_Tool实例中。

//导入自定义的翻译工具
import XL_Translation_Tool, { TranslationForm } from 'ets/XL_Modules/XL_Translation_Tool'

//主页面UI
@Entry
@Component
struct Index{
  ......
}

//自定义弹窗
@CustomDialog
struct dialog1{

  dialogController:CustomDialogController
  @Link If_Provide_Developer_Info:boolean
  @State private Baidu_AppId:string = ''
  @State private Baidu_Key:string = ''

  build(){
    Column(){

      Text('APP Id: ')
        .fontSize(20)
        .fontWeight(600)
        .fontColor(Color.Gray)
        .margin({
          top:20,
          bottom:4
        })
        .width('86%')

      TextInput()
        .type(InputType.Number)
        .width('95%')
        .height(40)
        .backgroundColor('#eeeeee')
        .onChange((value:string) => this.Baidu_AppId = value)

      Text('密钥: ')
        .fontSize(20)
        .fontWeight(600)
        .fontColor(Color.Gray)
        .margin({
          top:20,
          bottom:4
        })
        .width('86%')

      TextInput({
        text:this.Baidu_Key
      })
        .type(InputType.Password)
        .width('95%')
        .height(40)
        .backgroundColor('#eeeeee')
        .onChange((value:string) => this.Baidu_Key = value)

      Row(){
        Text('确认')
          .fontSize(24)
          .fontWeight(700)
          .fontColor(Color.Blue)
          .onClick(() => {
            this.dialogController.close()
            this.If_Provide_Developer_Info = true
            XL_Translation_Tool.provideDeveloperInfo(this.Baidu_AppId, this.Baidu_Key)
          })

        Text('取消')
          .fontSize(24)
          .fontWeight(700)
          .fontColor(Color.Red)
          .onClick(() => {
            this.dialogController.close()
          })
      }
      .width('100%')
      .margin({
        top:30
      })
      .justifyContent(FlexAlign.SpaceEvenly)


    }
    .height(260)
    .width('92%')
  }

}

最后,编写页面入口Index。dialogController表示自定义弹窗组件dialog1的控制器。

//导入自定义的翻译工具
import XL_Translation_Tool, { TranslationForm } from 'ets/XL_Modules/XL_Translation_Tool'

//主页面UI
@Entry
@Component
struct Index {

  @State private If_Provide_Developer_Info:boolean = false
  @State private translation_mode:number = TranslationForm.From_En_To_Zh

  @State private translation_content:string = ''
  @State private translation_result:string = ''

  private dialogController = new CustomDialogController({
    builder:dialog1({
      If_Provide_Developer_Info:$If_Provide_Developer_Info
    })
  })


  private async Begin_Translate(){
    let result = await XL_Translation_Tool.translate(this.translation_content, this.translation_mode)
    this.translation_result = result.result
  }

  build() {
      Column() {

        Text('百度翻译API')
          .fontSize(36)
          .fontColor(Color.Pink)
          .fontWeight(800)
          .margin({
            top:20
          })


        Row(){

          Row() {
            Text('英译中')
              .fontSize(20)
              .fontColor('#8099ff')
              .fontWeight(800)

            Image($rawfile('image2.png'))
              .height(30)
              .width(30)
          }

          Text('提供密钥')
            .fontSize(20)
            .fontColor('#ff6666')
            .fontWeight(800)
            .onClick(() => this.dialogController.open())

        }
        .margin({
          top:20
        })
        .width('100%')
        .justifyContent(FlexAlign.SpaceEvenly)

        Text('输入')
          .fontSize(20)
          .fontWeight(600)
          .fontColor(Color.Gray)
          .margin({
            top:30,
            bottom:10
          })
          .width('86%')


        TextArea()
          .width('90%')
          .height(120)
          .border({
            width:3,
          })
          .onChange((value:string) => this.translation_content = value)
          .fontSize(21)

        Text() {
          Span('结果')
        }
        .fontSize(20)
        .fontWeight(600)
        .fontColor(Color.Gray)
        .margin({
          top: 30,
          bottom: 10
        })
        .width('86%')


        TextArea({
          text:this.translation_result
        })
          .width('90%')
          .height(150)
          .border({
            width:3,
          })
        .fontSize(21)


        Row(){

          Image($rawfile('image1.png'))
            .height(40)
            .width(40)

          Text('翻译')
            .fontWeight(700)
            .fontSize(24)
            .fontColor(Color.White)
            .margin({
              left:20
            })

        }
        .width('93%')
        .height(50)
        .backgroundColor('#8099ff')
        .borderRadius(30)
        .justifyContent(FlexAlign.Center)
        .margin({
          top:50
        })
        .onClick(() =>{
          if(!this.If_Provide_Developer_Info){
            this.dialogController.open()
            return
          }
          console.info('------[ArkUI] '+'--'+this.translation_content+'--')
          this.Begin_Translate()
        })


      }
      .width('100%')
  }
}

//自定义弹窗
@CustomDialog
......

这样之后,调用百度API的案例便编写完成了,使用模拟器或真机可以查看运行效果。受一些奇怪的bug的影响,本案例中的翻译功能只支持英译中。

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为资料太多,太杂,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。 

为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:

希望这一份鸿蒙学习文档能够给大家带来帮助~


 鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频教程+学习PDF文档

(鸿蒙语法ArkTS、TypeScript、ArkUI教程……)

 纯血版鸿蒙全套学习文档(面试、文档、全套视频等)

                   

鸿蒙APP开发必备

​​

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2102609.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT+OSG+osg-earth显示一个球

目录 1、环境配置 2、在QT Creator导入相关的库 3、代码部分 4、运行过程中的问题 5、相关参考 重要衔接&#xff1a;QTOSG显示一个三维模型-CSDN博客 1、环境配置 系统&#xff1a;windows10系统 QT:版本5.15.2 编译器&#xff1a;MSVC2019_64bit 编辑器…

Conda在线/离线迁移虚拟环境

conda简单使用 1.创建环境&#xff1a; conda create -n myenv python3.82.激活环境 conda activate myenv3.退出环境 conda deactivate4.安装包 pip install xxx5.列出所有环境 conda env list conda info --envs6.删除环境 conda remove -n myenv --all离线迁移conda …

GD32F103单片机-概述和工程建立

GD32F103单片机-概述和工程建立 一、GD32F103单片机介绍1.1 GD32F103C8T6引脚1.2 GD32F103C8T6系统架构和启动配置1.3 GD32F103C8T6时钟树 二、GD32F103工程建立 一、GD32F103单片机介绍 GD32F103系列由是由国内公司兆易创新生产的基于Arm Cortex-M3处理器的单片机位数&#x…

陪诊志愿服务正在开展,喜鹊医疗打造国内首家陪诊聚合平台

2024年8月&#xff0c;为了培养一支专业、合格的陪诊志愿服务队伍&#xff0c;为志愿者提供就业帮扶&#xff0c;也满足社会日益增长的健康需求。由喜鹊医疗捐赠专项资金&#xff0c;中国民族卫生协会联合中国志愿基金会共同开展“健康中国行&#xff0c;陪诊惠民工程——陪诊志…

django学习入门系列之第十点《django中数据库操作--创建与删除表》

文章目录 django创建与删除表开始创建表创建指令新增表删除表删除列新增列修改报错提示语言总结 往期回顾 django创建与删除表 删除表 创建表 修改表 操作目录 开始创建表 class text_into(models.Model):name models.CharField(max_length32)password models.CharField…

二手手机回收小程序搭建,小程序功能特点

随着社会生活水平的提高&#xff0c;对手机的更新换代的速度也在逐渐加快&#xff0c;出现了大量的闲置手机&#xff0c;而这也给手机回收市场带来了巨大的发展空间&#xff01; 目前&#xff0c;手机回收市场进入到了发展快速期&#xff0c;吸引了越来越多的企业加入大市场中…

java重点学习-spring

三 spring 3.1 Spring框架中的单例bean是线程安全的吗? 不是线程安全的 Spring框架中有一个Scope注解&#xff0c;默认的值就是singleton&#xff0c;单例的。 因为一般在spring的bean的中都是注入无状态的对象&#xff0c;没有线程安全问题&#xff0c;如果在bean中定义了…

基于纠错码的哈希函数构造方案

一、前言 随着大数据时代的到来&#xff0c;交通数据量急剧增加&#xff0c;由此带来的交通安全问题日益凸显。传统的驾驶人信用管理系统在数据存储和管理上存在着诸多不足之处&#xff0c;例如中心化存储方案无法有效地进行信用存证及数据溯源。区块链技术以其去中心化和不可…

移动硬盘无法访问怎么修复?

移动硬盘是一种方便的存储设备&#xff0c;但有时可能会遇到无法访问的问题。这不仅影响工作效率&#xff0c;还可能导致数据丢失。本文将详细介绍在Windows系统中移动硬盘无法访问怎么修复&#xff0c;帮助您恢复数据和硬盘功能。 移动硬盘无法访问的常见原因 硬盘故障&#…

1998-2023年上市公司金融/信贷/资本资源错配程度数据(含原始数据+计算代码+结果)

1998-2023年上市公司金融/信贷/资本资源错配程度数据&#xff08;含原始数据计算代码结果&#xff09; 1、时间&#xff1a;1998-2023年 2、来源&#xff1a;上市公司年报 3、指标&#xff1a;证券代码、year、应付账款、负债合计、利息支出、行业代码、是否ST或PT、上市日期…

Scott Brinker:Martech中的AI会让买家体验更好还是更糟?这取决于…….

Martech中的AI会让买家体验更好还是更糟&#xff1f; 你怎么知道自己正处于炒作周期的顶峰&#xff1f;当手段大于目的。 Martech专业人士和营销运营领导者正被推动将人工智能应用于营销——将其用于任何事情&#xff01;——相信人工智能的自动化和加速&#xff0c;尤其是生…

通过EasyExcel设置自定义表头及设置特定单元格样式、颜色

前言 在项目开发中&#xff0c;我们会遇到各种文件导出的开发场景&#xff0c;但是这种情况并都不常用&#xff0c;于是本人将自己工作中所用的代码封装成工具类&#xff0c;旨在记录工具类使用方法和技术分享。 实战代码 导出效果&#xff1a; 1、导入依赖 <dependency&g…

开发指南058-JPA多数据源

一般情况下&#xff0c;一个微服务只链接一个数据库&#xff0c;但是不排除有些情况下需要链多个库。链多个库比较复杂&#xff0c;介绍如下&#xff1a; 1、nocas中要配置多数据源 白框内为正常的单数据库情况。下面增加标识&#xff08;可以任意起&#xff0c;这里为eva)&…

Maven入门:自动化构建工具的基本概念与配置

一、什么是Maven 目前无论使用IDEA还是Eclipse等其他IDE&#xff0c;使用里面 ANT 工具帮助我们进行编译&#xff0c;打包运行等工作。Apache基于ANT进行了升级&#xff0c;研发出了全新的自动化构建工具Maven。 Maven使用项目对象模型&#xff08;POM-Project Object Model&…

ARM基础---编程模型---ARM汇编

一、编程模型 1.1.数据和指令集 1.数据 ARM 采用的是32位架构。 ARM 约定:Byte &#xff1a; 8 bits Halfword &#xff1a; 16 bits (2 byte)Word : 32 bits (4 byte)Doubleword 64-bits&#xff08;8byte&#xff09;&#xff08;Cortex-A处理器&#xff09; 2.指令 ARM…

红日靶场vulnstack (三)

环境搭建 直接把靶机下载下来后&#xff0c;配置环境如下&#xff0c;直接Centsos配置多一张网卡NAT模式就行。 //只有这两台主机IP和图片不同&#xff0c;其它都是一样的&#xff0c;因为图片是拿别人的 kali&#xff1a;192.168.145.171 Centos&#xff1a;192.168.145.130…

https和harbor仓库跟k8s

目录 https 做证书 harbor仓库 https https是加密的http&#xff0c;它的端口是443&#xff0c;它的协议是tcp协议。建立连接和普通的tcp是一样的&#xff0c;都是三次握手和四次挥手&#xff0c;但是它三次握手之后有一个步骤&#xff1a;SSL或者TLS握手的过程&#xff0c…

DAMA数据管理知识体系(第4章 数据架构)

课本内容 4.1 引言 概要 数据架构考虑方面 数据架构成果&#xff0c;包括不同层级的模型、定义、数据流&#xff0c;这些通常被称为数据架构的构件数据架构活动&#xff0c;用于形成、部署和实现数据架构的目标数据架构行为&#xff0c;包括影响企业数据架构的不同角色之间的协…

vue3+ts 实现模板表格文件下载~

1、效果图&#xff1a; 2、创建点击事件&#xff0c;并发起请求&#xff0c;获取模板表格文件下载url地址。 //组件 <a-button class"btn btn_width" click"download"> 下载模板 </a-button>// 文件模板下载 import { getTemplate } from /ap…

JAVA读写Excel(jxl,poi,easyExcel)

目录 一、需求描述 二、具体操作Excel的常用方法 方法一&#xff1a; 使用jxl 方法二&#xff1a; POI 方法三&#xff1a;EasyExcel 三、总结 一、需求描述 前端有时候会传送 Excel 文件给后端&#xff08;Java&#xff09;去解析&#xff0c;那我们作为后端该如何实现…