2015-06-18 13:35:14 dongdong9223 阅读数 6788

1 简介

    搜狗语音云基于自主开发、领先业内的语音技术,力求为广大开发者提供最优质的语音服务,开发者只需简单集成语音云控件, 就可以通过API调用搜狗语音云服务,获得搜狗强大的语音技术支持,更加专注于业务需求的开发。

2 提供的服务

  • 在线语音识别技术:

    官方语:该技术让计算机可以“听懂”人类语音,通过机器将语音信号转变为相应的文本。

    说白了:就是联网解析语音为文本。

  • 离线语音识别技术:

    官方语:该技术通过本地离线语音包直接将语音输入识别转变为文字,从而代替云端服务器功能。

    说白了:就是离线解析语音为文本,不用联网了。

  • 在线听歌识曲技术:

    官方语:该技术基于搜狗自有技术,向广大中小开发者提供免费高效的听歌识曲服务。 从此查找歌名不必大费周章,只需录制提交音乐片段,由搜狗音乐云自动给出演唱者和歌曲名称。

    说白了:就是找周杰伦的歌更不好找了。

  • 离线语音合成技术:

    官方语:该技术可以让计算机将外部输入的文本信息转变为自然流畅的汉语口语,使电脑具有类似于人一样的说话能力, 离线语音合成则无需依赖网络即可在设备上合成出高音质的语音。

    说白了:就是文本转语音。

3 如何使用

    看着真是高大上啊,语音服务神秘难懂,现在只需简单调用,哪里不会调哪里,从此妈妈再也不用担心我的学习了,so easy

3.1 使用步骤

    使用步骤也不难。

    首先,需要注册一个搜狗语音云账号。

    其次,登陆后在左边的“应用信息”中选择要申请的服务:

      

    如图所示,也可以进行“快速体验”。如果你是没有用过搜狗语音云服务的新手,推荐进入快速体验区进行快速体验,好处是不用搜狗审核就可以快速获取appId来调用服务,缺点就是服务次数受限制,不过一天500次一般也够用了:

      

    点击右上角“我的应用”,就可以看到快速申请的appId了:

    

    记录号id信息,服务中要用哦!

   

3.2 调用服务

    这里该说说在客户端怎么调用了,以使用“快速体验”申请在“Android”平台上使用“语音识别”为例。

我们先来看看搜狗除了给了我们appId之外还给了我们什么...

    

    第一个是调用的SDK包,第二个是调用说明。

    将SDK包中,libs文件夹下的文件:

    

    一股脑的放入你的Android工程的libs里面,并在工程中将sogou-srop.jar引入Build Path

  修改AndroidManifest.xml,需要确保app具有以下权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />


    在你的布局页面里面放入一个按钮:

<span style="font-size:18px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.testyuyin.MainActivity$PlaceholderFragment" >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我要说话!" />

</RelativeLayout></span>

    在activity中的调用代码:

<span style="font-size:18px;">package com.example.testyuyin;

import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;

import com.sogou.speech.listener.RecognizerListener;
import com.sogou.speech.ui.RecognizerDialog;

public class MainActivity extends Activity {

	public static RecognizerDialog dialog;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		if (savedInstanceState == null) {
			getFragmentManager().beginTransaction()
					.add(R.id.container, new PlaceholderFragment()).commit();
		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);

			Button button = (Button) rootView.findViewById(R.id.button);

			dialog = new RecognizerDialog(getActivity(), "appId","accessKey", true, false);
			dialog.setlistener(new RecognizerListener() {

				@Override
				public void onResults(List<List<String>> arg0) {
					for (List<String> stringList : arg0) {
						System.out.println("Yuyin------------------");
						for (String s : stringList) {
							System.out.println("Yuyin:" + s);
						}
					}

					String[] ss = new String[arg0.get(0).size()];
					for (int i = 0; i < ss.length; i++) {
						ss[i] = arg0.get(0).get(i);
					}
					
					new AlertDialog.Builder(getActivity())
					.setTitle("您说的是:")
					.setSingleChoiceItems(
							ss, 0,
									new DialogInterface.OnClickListener() {
								
								@Override
								public void onClick(
										DialogInterface dialog,
										int which) {
									dialog.dismiss();
								}
							}).setNegativeButton("取消", null).show();

				}

				@Override
				public void onQuitQuietly(int arg0) {
					// TODO Auto-generated method stub

				}

				@Override
				public void onPartResults(List<List<String>> arg0) {
					// TODO Auto-generated method stub

				}

				@Override
				public void onError(int arg0) {
					// TODO Auto-generated method stub

				}
			});

			button.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					dialog.show();
				}
			});

			return rootView;
		}
	}

}</span>

    看到没?我们先定义了一个dialog,这是引用的搜狗语音的语音对话框。然后给dialog设置一个监听:RecognizerListener,它来监视用户的语音行为。注意“appId”和“accessKey”换成申请之后获取到的值。当然这里面要实现一些回调函数。

    在函数onResults里面,我们可以定义获取了语音结果之后的行为。我们来看看onResults这个函数:

<span style="font-size:18px;">public void onResults(List<List<String>> arg0)</span>

    可以看到它的函数是个两层list。也就是说,我们说话的时候,有可能说了好几句,而每句话,都有可能有不同的结果。比如你说了:

    你好啊!

    吃饭了吗!

    其中,“你好啊”识别成的备选项可能有“你好啊”,“你好吗”,“你好啦”等。

    “吃饭了吗”识别成的备选项可能有“吃饭了吗”,“吃饭了没”,“吃饭了啊”等。

    所以,该函数参数的第一维list是说的不同的话,第二维是每句话的不同识别。明白了吧?明白了吗?

    我们在例子中只识别第一句话,让屏幕弹出个对话框让我们选择。最后,让按钮与搜狗语音的dialog绑定,点击按钮弹出语音识别服务dialog

3.3 客户端使用

    直接上图:

    

    

    点击“我要说话!”:

    

    对着手机说“你好”:

    

    选择你的本意,后台得到文本就可以为所欲为啦!很简单吧!更多的应用可以参考搜狗的示例程序及SDK文档。

2016-12-24 12:58:58 snow2know 阅读数 7517
导读

11 月 21 日到 23 日,搜狗、百度和科大讯飞三家公司接连召开了三场发布会,向外界展示了自己在语音识别和机器翻译等方面的最新进展。值得注意的是,这三家公司几乎在同一时段宣布了各自中文语音识别准确率达到了 97%。

其中搜狗语音团队在 11 月 21 日推出了自己的语音实时翻译技术。搜狗的这项技术主要包括两个方面,分别是语音识别和机器翻译。根据该团队的介绍,搜狗语音识别的准确率达到了 97%,支持最快 400 字每秒的听写。
百度则在 11 月 22 日宣布向开发者开放了情感合成、远场方案、唤醒二期和长语音方案等四项语音识别技术。百度语音开放平台自 2013 年 10 月上线以来每日在线语音识别请求已经达到了 1.4 亿次,开发者数量超过 14 万。在如此庞大的数据支撑下,百度语音在“安静条件下”的识别准确率达到了 97%。
image
另外,在 11 月 23 日的科大讯飞发布会上,科大讯飞轮值总裁胡郁引述了罗永浩在 9 月锤子发布会上的演示数据,表示科大讯飞的语音输入识别成功率也达到了 97%,即使是离线识别准确率也达到了 95%。
20161021050708410
针对中文语音识别准确率提升背后到底隐藏着哪些技术和准确率继续提升还需要突破哪些困难等问题,PingWest 品玩分别采访了搜狗语音交互中心技术负责人陈伟和百度首席科学家吴恩达。

陈伟表示,搜狗语音识别的目标是更自然的,更像任何人交互的方式靠近。因此自从 8 月份发布“知音引擎”后,搜狗就开始基于已有的深度学习平台搭建自己的识别引擎。在搭建这个引擎的过程中,搜狗做的第一件事情就是按照人类讲话时的生物特征将每一个音节分为一个个独立的帧,并根据其波形判断此时是语音还是静音状态,从而让语音识别的效率大为提升。

第二是在语音识别框架下建立一个声学模型,根据人在发音时声音信号和录音信号波形的对比,实现录音和文字之间的映射。

在此基础上,搜狗语音需要的就是用大量数据来训练这个深度学习模型,而在中文手机输入法中市场占有率遥遥领先的搜狗输入法刚好为搜狗带来了所需的数据。“我们每天的语音请求次数在 1.9 亿次左右,也就是大约 16 万小时的语音数据,有了这些数据以及我们前沿的深度学习技术,我们在语音识别取得比较好的效果,这也是能使我们语音实时翻译成功的重要因素。”陈伟说。
300000931099127952960461732_950
在接受 PingWest 品玩采访时,百度首席科学家则表示 97% 的语音识别准确率是百度技术团队多年研发的成果。在百度语音团队的努力下,百度语音识别的错误率每年能够下降 20% 到 30%。吴恩达表示,百度语音识别准确率的不断提升还离不开算法的不断更新和数据的积累。

但除了识别率的提升,百度的语音识别还考虑到了环境和感情等方面的问题。例如在比较空旷和嘈杂的环境里,百度语音团队给出的远场方案可以基于麦克风阵列,利用麦克风阵列束形成、语音增强、回声消除、声源定位等技术综合实现高准确率远场识别。吴恩达称开发者可以利用这一技术让语音识别距离增加 3-5 米,解决长时间语音识别的准确率。

在语音识别领域耕耘多年的科大讯飞在这一次的发布会上也宣布将会将自己的技术应用到多个领域,并将其语音平台开放给开发者。根据科大讯飞研究员副院长魏思此前发表的一篇文章,讯飞语音识别准确率提升的秘诀是讯飞研发的一种名为前馈型序列记忆网络 FSMN 的新框架。

魏思说,相对于传统的深度学习模型,讯飞的前馈型序列记忆网络增加了一个“记忆块”的模块来存储对判断当前语音帧有用的历史信息和未来信息,实现语音识别中的“端到端”建模。

另外,讯飞语音识别系统还集成了一个由语音自动切分、自然语言处理和声纹识别等技术组成的语音转写引擎。在此基础上,科大讯飞最创新的一点就是为不同场景下的语音识别做了大量的定制工作,例如讯飞语音识别系统能够实现会议或者采访场景中的对话角色自动分离。
1722082
除了 97% 这个数字上的巧合,百度、搜狗和讯飞这三家公司都对自己的手机输入法进行了语音识别方面的升级。其中科大讯飞已经将野心延展到了物联网上,并推出了一款“万物联网输入法”,想通过语音操作的方式解决物联网设备的人机交互问题。而搜狗也计划在下一个版本的搜狗手机输入法中加入实时语音翻译功能。

根据比达咨询发布的《2016 年第三季度中国第三方手机输入法市场研究报告》,本季度中国第三发手机输入法越活越用户数排名前三的分别是搜狗输入法、百度输入法和讯飞输入法。

很明显这三家公司在语音识别领域最大的竞争点就是手机输入法。相比于在手机屏幕上使用拼音打字,语音输入不仅会让输入效率大幅提升还能解放用户的双手。但囿于语音识别准确率的限制,此前各大手机输入法厂商仅仅是将语音输入当作一个附加功能放在输入法的键盘里。现在随着技术的进步,语音识别准确率正在逐渐提升。而物联网时代的到来,语音识别必然成为物联网终端最重要的人机交互模式。

从市场份额上看,搜狗输入法一直都遥遥领先于其他两位竞争对手。如果百度和讯飞想要改变这一现状,就只能在未来必然成为主流的语音输入上先发制人。现在这三家公司在语音识别准确率上的较量,谁又能说他们不是在争夺物联网时代人机交互市场。

本文转载自:http://www.linuxprobe.com/sogou-speech-recognition.html

免费提供最新Linux技术教程书籍,为开源技术爱好者努力做得更多更好:http://www.linuxprobe.com/

2016-10-07 15:14:32 Alex_wsc 阅读数 1281

语音识别和友盟统计

语音识别

  • 第三方开发者可以使用的

    1. 科大讯飞
    2. 盛大
    3. 云知声(上地)
  • 自己使用

    1. 百度语音(第三方也可以使用)
    2. 腾讯
    3. 搜狗
  • 苹果,IBM,微软,google的中文识别都没有国内的好

*chrome 浏览器的input标签有时候会出现麦克风的突变

  • google:
    • 1、VoiceSearch.apk插件
    • 2、高级(隐藏chrome语音识别的API)
    • 3、谷歌未公开语音识别:国内文章介绍这里

友盟统计

  • 【友盟+】全球领先的第三方全域大数据服务提供商。通过全面覆盖PC、手机、传感器、无线路由器等多种设备数据,打造全域数据平台。
  • 可以查看各个行业的数据,比如android手机设备、系统、分辨率、联网模式等市场占有率,按照设备指数、社交指数、应用指数
    、市场指数分类。
  • 是数据统计领域的老大,数据可信暂不考虑
  • 使用友盟统计可以统计APP的下载量以及使用具体情况
2017-08-27 17:05:52 yutianzuijin 阅读数 6544

如果大家使用搜狗输入法的语音识别可能会发现在我们说我一句话之后,语音识别会返给你多个结果,这些结果之间只有微小差异(很多时候是发音相同的替代词)。绝大多数时候,输入法给出的结果就是我们需要的,但是偶尔也会出现候选结果中的才是我们需要的。你可能会好奇这些候选结果是如何产生的,在本文中我就给大家简单介绍一下。

one best

最初的语音识别结果只有一个,也被称为one best,即一个最优结果。语音识别解码器通过声学模型和语言模型对用户输入的语音进行打分,输出一个得分最高的结果。其基本公式为:

P=argmaxWN1WP(WN1|X)

其中,X=x1,x2,,xT表示输入的观察向量时间序列,WN1=w1,w2,,wN表示词典中词组成的词串。上述公式的含义就是:给定一段语音特征序列,输出可能性最大的词串组合,所以语音识别是一个带有回溯的最优化搜索问题。
根据Bayesian公式,条件概率可以变为:
P(WN1|X)=P(X|WN1)P(WN1)P(X)

由于P(X)与求解无关,上面公式可以变为:
P=argmaxWN1WP(X|WN1)P(WN1)

上述公式分为三部分,arg max其实就是解码器,P(X|WN1)是声学模型,P(WN1)是语言模型。解码器是语音识别的核心,它调用声学模型和语言模型,采用维特比算法获得最优的词序列。one best即是通过回溯最优得分得到的最优路径。

lattice

在实际的语音识别系统中,最优路径不一定与实际字序列匹配,我们一般希望能够得到得分最靠前的多条候选路径,即N-best。为了紧凑地保存候选路径,防止占用过多内存空间,我们一般采用lattice(又叫词图)来保存识别的候选序列。lattice本质上是一个有向无环(directed acyclic graph)图。图上的每个节点代表一个词的结束时间点,每条边代表一个可能的词,以及该词发生的声学得分和语言模型得分。
原始lattice
在生成one best结果时,只需要从最优结果处回溯,但是为了生成lattice,我们需要保留更多信息。具体就是在生成每一个hist的时候保留多个候选alt,这样在回溯best hist的时候也访问alt来生成lattice。可以认为原始hist是有效信息在节点上的lattice,而上图中的lattice有效信息都在边上。
在lattice上从左向右的任何一条路径,就构成一个识别结果,路径上每条边的声学得分相加,再加上路径对应的语言得分,就是整条路径的得分,通常取得分最大的前 N 条路径对应的词串作为识别的 N-Best 结果输出。上面lattice的生成用的语言模型往往不够精确,通常还需要在lattice上用更大的语言模型进rescore。

lattice剪枝

原始lattice可能会非常庞大,上图给出的只是一个很小的lattice,这时我们可以对lattice进行剪枝但是不影响最终的准确率。一种剪枝方法是对lattice进行前后向打分,计算每条边的后验概率,然后删除后验概率很低的边。对上图进行剪枝后获得下图:
剪枝的lattice
相比原图,上面的lattice简化了不少,但是最重要的信息并没有丢失。通过计算后验概率,我们还可以很容易地知道每条边在整个lattice中的重要性。

confusion network

混淆网络是一种特殊的lattice,由原始lattice经过变换生成。它要求lattice中的每条路径都必须经过所有的节点。如下图所示:
混淆网络
简单描述一个近似于srilm中采用的混淆网络生成算法:首先进行前后向概率打分计算每条边的后验概率;其次根据后验概率对lattice进行剪枝;再次从原始lattice中选择一条得分最高的路径当作初始混淆网络(路径中的节点即为混淆网络中的节点);最后就开始逐步将其他的边对齐添加到上述初始混淆网络中。特别地,如果在添加某条边到某节点中时发现已经有边指向该边并且也添加到该节点之后,则创建一个新的节点,让之前的边都指向新节点,要添加的边则从新节点指向之前的老节点。
相比于lattice,我们可以很容易从混淆网络中获取one best结果,只需要从每一段中选择后验概率最大的边即可。混淆网络作为lattice的简化版,会引入原始lattice中不存在的路径。但是通常情况下,用混淆网络获取的one best结果要好于原始的one best。混淆网络还有一个好处,我们可以很容易获取每个时刻相互竞争的词有哪些,怀疑苹果自带的输入法即采用了混淆网络来修改候选词。

2012-09-07 13:24:22 maimode 阅读数 67

本文介绍使用android.speech包下的api实现一个简单的语音识别例子。

 

speech api参考:http://developer.android.com/intl/zh-CN/reference/android/speech/package-summary.html

 

android开发入门参考:http://maimode.iteye.com/blog/1634268

 

下文给出核心的代码部分:

 

EgSpeechActivity(启动的activity)

 

package com.example.androideg.speech;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class EgSpeechActivity extends Activity implements OnClickListener {
	 public final static String EXTRA_MESSAGE = "com.example.androideg.speech.MESSAGE";
	 
	 private static final int VOICE_RECOGNITION_REQUEST_CODE = 1001;  
	 private static final String SPEECH_PROMPT = "请讲话";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
		// 检查是否存在recognition activity
		PackageManager pm = getPackageManager();
		List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(
				RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
		Button btn = (Button) findViewById(R.id.btn_speek);
		if (activities.size() != 0) {
			//如果存在recognition activity则为按钮绑定点击事件
			btn.setOnClickListener(this);
		} else {
			// 如果不存在则禁用按钮
			btn.setEnabled(false);
			btn.setText("语音识别不可用");
		}

    }

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.btn_speek){
			startVoiceRecognitionActivity();
		}
	}
	
	/**
	 * 启动语音识别activity,接收用户语音输入
	 */
	private void startVoiceRecognitionActivity(){
		//通过Intent传递语音识别的模式  
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);  
        //语言模式:自由形式的语音识别  
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        //提示语音开始  
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, SPEECH_PROMPT);  
        //开始执行我们的Intent、语音识别  并等待返回结果
        startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// 确定是语音识别activity返回的结果
		if (requestCode == VOICE_RECOGNITION_REQUEST_CODE){
			// 确定返回结果的状态是成功
			if (resultCode == RESULT_OK){
				// 获取语音识别结果  
	            ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);  
	            startDisplayMessageActivity(matches);
			}
		}
		
		super.onActivityResult(requestCode, resultCode, data);
	}
	
	/**
	 * 启动展示activity,显示识别结果
	 * @param message
	 */
	private void startDisplayMessageActivity(ArrayList<String> strList){
		Intent intent = new Intent(this, DisplayMessageActivity.class);
    	intent.putExtra(EXTRA_MESSAGE, strList);
    	startActivity(intent);
	}
}

相应的layout文件activity_main.xml:

 

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".EgSpeechActivity" >


    <Button
        android:id="@+id/btn_speek"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/button_speak" />

</LinearLayout>

 

DisplayMessageActivity(用于展示识别结果):

 

 

package com.example.androideg.speech;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class DisplayMessageActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		// 设置布局
		setContentView(R.layout.activity_display_message);
		
		// 从intent中获取数据
		Intent intent = getIntent();
		ArrayList<String> strList = intent.getStringArrayListExtra(EgSpeechActivity.EXTRA_MESSAGE);

		//找到list,然后赋值
		ListView list = (ListView) findViewById(R.id.list);
		list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strList));
    }

}
 

 相应的layout文件activity_display_message.xml:

 

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >
    </ListView>

 </LinearLayout>

 

经过测试,需要在网络支持的环境下才能识别,支持中文识别。 

 

附件有本示例的eclipse项目文件。

 

运行界面:

 

 

 

 

没有更多推荐了,返回首页