如何开发出你自己的Siri应用程序?

译文
移动开发 Android
本文将帮助大家了解如何编写属于自己的Siri应用程序。去年我曾负责开发过一款Android Siri应用,目前这款软件已经完成并被摆上Google Play的货架。希望我的亲身经历能为大家带来启示。

什么是移动助手应用?

[[75855]]

【2013年6月26日 51CTO外电头条】移动助手应用应当包含以下功能:

  • 它应是一款移动应用(包括Android、iOS、Windows Phone等平台),
  • 大家可以通过文字或语音进行提问,
  • 大家可以通过文字、语音、图像或者活动获得应答信息,
  • 它应涉及移动设备中固有的功能,例如麦克风、屏幕、GPS、互联网、扬声器以及存储在设备中的信息。

移动助手应用能做些什么?

移动助手应用能实现很多功能,我所开发的首个版本仅仅能够理解并回应十五条指令,但如今它已经能够理解并回应超过五十条指令。基础指令类型应当包含新闻、天气、闹钟设置以及呼叫联系人等。在移动市场中搜索移动助手软件时,我发现以上几类指令最为通用。下面我就列出一份需要预置在内指令列表,帮助大家的移动助手具备基本功能。

  • 设置闹钟
  • 从新闻、天气、赛事比分及维基百科中获取信息
  • 运行应用程序
  • 打开媒体文件(包括视频与音乐)
  • 在Facebook或者twitter等社交平台上分享内容
  • 读取/编写短信或电子邮件
  • 读取某些社交媒体分享内容
  • 寻找最近的市场、药房、医院及餐厅等
  • 呼叫某人
  • 处理基本数学问题
  • 检查银行存款余额
  • 向某人汇出款项
  • 检查最近的货币或证券交易信息
  • 读取/设置日程表
  • 购买演唱会或旅行票据
  • 诸如此类

其中一些指令类型可以与第三方公司的业务相集成。举例来说,大家可以通过集成让自己的移动助手向Amazon或者Best Buy下达货品订单。

市场上现有移动助手汇总

目前市场上已经存在六十多种知名手机助手产品,其中人气最高的当数Siri以及谷歌语音搜索方案。

以下表格列出了市场上的现有移动助手及其开发环境(编者注:仅包括国外)。

  • Siri,
  • 谷歌语音搜索,
  • Nuance Nina,
  • Dragon移动助手,
  • Angel Lexee,
  • AIVC,
  • Iris,
  • Skyvi,
  • EverFriends,
  • EasyLuncher,
  • Speaktoit,
  • Evi,
  • Turkcell Mobil Asistan(土耳其)。
[[75856]]

Siri与谷歌语音搜索人气最高,也就无需赘述。下面我向大家介绍关于Nina、Lexee、Dragon移动助手以及Turkcell Mobil Asistan的简要信息。

Nuance Nina: Nuance公司专为大型企业提供用于开发自有移动助手应用的SDK,开发成果可以充当企业客户的服务应用。这款SDK可与iOS及Android应用相集成。感兴趣的朋友不妨点击此处查看其官方网站的介绍信息。

Lexee: Lexee是一款来自Angel Labs公司的移动助手,同时也提供足以创建自有移动助手的网络环境。大家可以添加、更新及删除各类方案,且无需通过网络接口进行编码。Lexee另一大值得称道的重点在于分析工具。Angel Labs非常擅长分析工具的开发,因此Lexee环境也给用户带来专业级别的使用报告及数据汇总选项。

感兴趣的朋友可以点击此处了解更多信息并查看介绍视频。

Dragon移动助手: Dragon移动助手是Nuance公司带来的又一力作。Dragon移动助手允许用户通过自然语言访问各类内容,并轻松在手机上完成日常工作。大家可以点击此处查看更多相关资料。

点击此处则能够下载这款应用,并观看我个人最喜爱的移动助手介绍视频。

Turkcell Mobil Asistan: Turkcell Mobil Asistan是Google Play商店中惟一一款来自土耳其的移动助手应用。Turkcell欧洲最大的全球移动通信企业之一。通过这款应用程序,大家可以为客户提供包括手机账单查询、流量资费信息在内的各种辅助性服务。另外,它还能回答用户关于伊斯坦布尔本地新闻、天气、货币以及交通情况的问题。

大家可以点击此处了解更多关于Turkcell Mobil Asistan的信息并下载这款应用。

#p#

移动助手中的技术要点

我希望上述信息能帮助大家了解移动助手的基本概念。下面我们再来看看关于这类应用程序的一些技术要点。移动助手应用应当涉及以下技术项目:

  • 语音到文本(简称STT)引擎
  • 文本到语音(简称TTS)引擎
  • 标签(智能)
  • 降噪引擎
  • Voice Biometrics,语音生物识别技术
  • Speech Compression Engine,语音压缩引擎
  • 应答用户界面
  • STT: Speech2Text引擎能够将来自用户的语音转化为文本信息。语音内容应可以来自语音文件或者数媒体信息。
  • TTS: Text2Speech引擎能够将文本内容转化为语音信息。将回答文本转化为语音形式非常重要,在用户驾车等特殊情况下尤其如此。
  • 标签: 由STT创建出的文本内容有时候会比较复杂。标签技术的介入能够快速识别出用户希望通过语音表达的主要意见。举例来说,如果用户询问明天应该穿什么样的衣物,标签引擎会将信息记入天气或者日程表标签。
  • 降噪引擎: 用户输入的语音信息有时候不太清晰,其中混入的噪音(例如空调机噪音)可能影响识别效果。降噪引擎会从语音中将白噪音消除掉。
  • 语音生物识别技术: 移动助手能够提供基于账户的细节信息,例如信用卡月度报告等。跟金钱挂钩的当然是大事,因此身份识别机制就显得极为重要。语音生物识别技术正是身份验证方案中的一种。通过这种技术,移动助手能够验证使用者的身份,从而决定是否允许其进行系统操作。
  • 语音压缩引擎: 如果助手工作起来速度缓慢,用户很可能由于失去耐心转而打开浏览器去网上寻找答案,这就让大家的心血付之东流了。互联网通信状态非常重要,而传输过程中所使用的数据包大小也同样关键。小数据包的传输速度更快、获取结果的速度也更为出色。有鉴于此,一款优秀的移动助手应用必须具备语音压缩引擎。客户端需要通过发送语音压缩包来实现快速反应。不过语音压缩与普通压缩有所区别,这是因为语音文件中并不存在我们平时所见的重复数据。大家最好选用G711压缩算法,它的胜出主要因为这种算法不会造成数据丢失。
  • 应答用户界面: 在服务器发回处理结果后,应用会播放一段语音应答,而设备屏幕中的应答界面也需给出对应信息提供。我个人的建议是,请不要使用本机组件,因为这样会给应用造成限制。最好采用基于网络的用户界面,这种应用界面能够更方便地在不同系统平台中正确运作。

移动助手架构解析

移动设备与主服务器之间必然存在通信流,因为用户当然不希望在使用应用的同时还要苦等语音数据下载完成。对于助手类应用而方,速度的重要性不言而喻——速度越快、用户的使用感受也就越自然。在理想状况下,用户甚至会感到自己像是真的在与客户代表或者助理开展交流。

当用户按下按钮、通过客户端提出问题,客户端会立即将问题一字节一字节地提交至主服务器(Main Server)。主服务器又将数据发送至STT服务器(STT Server),STT服务器从语音中整理出文本内容,然后将其传回主服务器。接下来,主服务器将文本发送至标签服务器(Tagging Server),旨在了解用户的实际需要。标签服务器为该条请求创建标签,例如“weather_info”。标签被发回之后,主服务器再次负责将标签信息传送至信息服务器(Information Server)。如果标签内容涉及身份验证机制,那么安全服务器(Security Server)将率先对其进行检查,然后才放行至信息服务器。最后,响应结果进入主服务器,主服务器据此创建响应文本、响应图像以及语音文本(借助TTS服务器)并将响应结果发送至移动设备。

信息服务器可以与第三方服务器进行通信,以获取某些原本并未存储在信息服务器当中的资讯。安全服务器则可以包含多种身份验证技术,例如语音生物识别技术、IMSI-IP半径查找、账号密码认证等等。

#p#

应答用户界面 

如果大家打算利用本机组件开发应答界面,那么最终软件成果将很难在不同类型的客户机上顺利实现显示格式与项目滚动的统一效果。我个人建议大家创建一套自定义Web视图,这样会让应答格式的添加变得更为轻松。

上面图片显示的是SiriWebView在屏幕中的显示效果。Web视图可由用户任意滚动,而且当新应答出现后、整个视图会自动向上移动。

在本节中,我将向大家简要介绍自己编写SiriWebView的过程。在这里大家将看到关于web视图的所有示例项目。向其它平台的用户们说声抱歉,此处所举的范例只适用于Android平台。

首先,创建一个新类,并将其命名为SiriWebView。它基本上属于由基本Android web视图做出的扩展。这个类应该包含并覆盖OnDraw函数,另外我们还应向其中添加两个新函数。其一用于创始化,其二则用于添加新应答内容。以下代码片段显示的就是如何添加新应答内容。

  1. public void AddNewCallOut(String message, Boolean ismsgResponse) { 
  2.         elementId = elementId + 1
  3.         StringBuilder messageBuilder = new StringBuilder(); 
  4.  
  5.         if (!message.contentEquals("")) { 
  6.  
  7.             if (!ismsgResponse) { 
  8.                 messageBuilder 
  9.                         .append("<table class='bubble-gray' cellspacing='0' cellpadding='0'><tr><td class='head'></td></tr>"); 
  10.                 messageBuilder 
  11.                         .append("<tr><td class='mid'><div class='txt shadow'>" 
  12.                                 + message + "</div></td></tr>"); 
  13.                 messageBuilder 
  14.                         .append("<tr><td class='foot'></td></tr></table>"); 
  15.             } else { 
  16.                 messageBuilder 
  17.                         .append("<table class='bubble-blue' cellspacing='0' cellpadding='0'><tr><td class='bhead'></td></tr>"); 
  18.                 messageBuilder 
  19.                         .append("<tr><td class='bmid'><div class='txt shadow'>" 
  20.                                 + message + "</div></td></tr>"); 
  21.                 messageBuilder 
  22.                         .append("<tr><td class='bfoot'></td></tr></table>"); 
  23.             } 
  24.  
  25.             loadUrl("javascript:document.getElementById(\"div" + elementId 
  26.                     + "\").innerHTML=\"" + messageBuilder.toString() + "\";"); 
  27.         } 
  28.         StringBuilder jvscr = new StringBuilder(); 
  29.         if (!ismsgResponse) { 
  30.             if (elementId != 1) { 
  31.                 if (!ismsgResponse) { 
  32.                     jvscr.append("var elem = document.getElementById('div" 
  33.                             + (elementId - 1
  34.                             + "');     var x = 0;     var y = 0;     while (elem != null) {         x += elem.offsetLeft;         y += elem.offsetTop;         elem = elem.offsetParent;     } "); 
  35.                     jvscr.append("var endj=500; var i=window.scrollY; for(i=window.scrollY;i<y;i++){ var j=0; var a=0; for(j=0;j<endj;j++) {a=a+1; }  window.scrollTo(x, i); } "); 
  36.                     loadUrl("javascript:" + jvscr.toString()); 
  37.                 } 
  38.             } 
  39.         } 
  40.     } 

该函数中涉及两个参数,分别是message与isResponse。大家可以在需要添加新应答内容时随意写入消息字串,并设定isResponse参数的值以调用该函数。该参数的作用是改变应答信息的字体颜色并滚动屏幕。在函数的第一行中,大家可以看到elementId参数。该参数对于对象的滚动处理非常重要。

在创建好自己的界面组件后,大家可以将成果添加到main_activity.xml当中,如下所示。

  1. <com.example.siriui.SiriWebView 
  2.           android:id="@+id/webview" 
  3.           android:layout_width="fill_parent" 
  4.           android:layout_height="fill_parent" 
  5.           android:keepScreenOn="true" 
  6.         android:layout_marginTop="0dp" 
  7.         android:layout_gravity="fill" 
  8.           android:layout_marginBottom="0dp" 
  9.           android:layout_marginLeft="0dp" 
  10.           android:layout_marginRight="0dp" 
  11.           android:scrollbars="horizontal" 
  12.            /> 

最终效果是什么样?大家可以参照前面给出的截图。

责任编辑:徐川 来源: 51CTO
相关推荐

2012-04-25 22:56:10

Android

2022-09-19 00:37:13

SaaS云计算开发

2012-04-26 22:32:01

Android

2018-12-11 11:41:14

物联网应用程序IOT

2013-11-19 15:35:01

2021-12-08 07:31:40

微服务架构程序

2021-11-24 09:00:00

云计算开发应用

2011-02-22 14:42:52

AndroidPad

2009-07-17 16:09:29

Swing桌面应用程序

2015-09-06 09:17:31

2013-02-22 09:28:45

MEAP软件移动应用开发HTML5

2012-02-08 15:06:31

ibmdw

2024-01-18 07:53:37

2020-08-25 14:03:20

应用程序屏蔽应用程序内保护网络攻击

2013-02-21 14:15:41

开发Tizen

2013-02-21 14:14:40

开发Tizen

2012-04-26 13:48:56

iPhone应用发布Ad Hoc

2011-05-24 16:09:57

Androi

2015-01-06 09:59:59

云应用程序Java开发SQL

2009-11-12 11:06:38

VS创建MFC应用程序
点赞
收藏

51CTO技术栈公众号