- 浏览: 347646 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (354)
- Flash | as3 (53)
- AIR | Starling (46)
- Android (55)
- Java (10)
- C++ (6)
- PHP (43)
- IOS (9)
- Unity3D (2)
- cocos2d-x (1)
- OpenGL (2)
- WebGL (3)
- Server (4)
- MemCache (13)
- MySql (2)
- NoSql (2)
- PhoneGap (13)
- jQuery | jQuery Mobile (14)
- javaScript | html5 | css3 (14)
- Linux (1)
- Box2D (2)
- SmartFox (1)
- Ruby (0)
- Python (2)
- Golang (11)
- Redis (1)
- 开源项目 (6)
- 游戏策划 (1)
- 云平台 (2)
- 项目管理 (6)
- 听见月光 (32)
最新评论
-
kenkao:
http://www.linuxidc.com/Linux/2 ...
解决idea编译时resources文件夹内容不自动复制到输出路径classes的问题 -
kenkao:
http://blog.csdn.net/yanwushu/a ...
解决idea编译时resources文件夹内容不自动复制到输出路径classes的问题 -
wpy126:
你这种比较根本不公平AppCan 用了多个页面,jqm内容都 ...
AppCan VS PhoneGap - 对比两大移动开发平台 -
kenkao:
zs12593 写道这个,这个
这里只是转载,建议看一下原文, ...
android游戏开发框架libgdx环境搭建 -
zs12593:
这个,这个
android游戏开发框架libgdx环境搭建
本文原创版权归 51CTO winorlose2000 所有,转载请按如下方式于文章显示位置详细标明原创作者及出处,以示尊重!!
作者:winorlose2000
Android TTS实现简单阅读器
简单的Txt文本阅读器,主要用于介绍Google Android的TTS接口。
一、TTS
在package android.speech.tts内,主要阅读下TextToSpeech.OnInitListener、TextToSpeech. OnUtteranceCompletedListener两个接口和TextToSpeech、TextToSpeech.Engine两个类。
具体还是自己去看下SDK文档吧。(我也是完整阅读过了的^^)
二、TTS引擎
以前在网上的例子,或者就我《Android基础样例》里的中文TTS例子,都是eSpeak引擎实现的。这种方式是要用其封装的TTS接口,再通过下载TTS数据使用。
而Android的SDK中还提供了TTS服务的接口,用于供应商提供服务的。也就是语音合成服务商只管提供它的服务,开发者只管使用Android的TTS接口,用户自己安装想要的服务自己进行选择。
总之呢,我用的是讯飞语音TTS v1.0。有两个文件,一个是Service程序,一个是语音数据。下载网址:http://soft.shouji.com.cn/down/22160.html
1)关于讯飞(貌似广告?)
好吧,少说点了,它也提供了个开发者平台。如下:
有试了下它那语音分析,话说,弹出的框框能不能好看点啊。(做个小话筒就好了么T^T)
恩,还有,现在讯飞是要开始宣传了么?貌似3月22日什么开发者大会-_-!(又广告了?)
2)其他中文引擎
参见文章:Android中文语音合成(TTS)各家引擎对比。(原网址打不开==,另外的网址就不贴了,搜下吧)
三、阅读器工程
现在学乖了,直接贴些代码得了==。代码中注释应该满清晰详细了^^。
1)界面布局
布局由main.xml includes header.xml & footer.xml组成,并写有了定时收起等。
TtsFatherActivity.java
- /**
- * 1)本类用于main.xml的布局控制。子类再去实现各控件的TTS相关功能。
- * 2)用继承方式实现是为了利用布局中控件的onClick属性(懒得多写代码==!)。
- */
- public abstract class TtsFatherActivity extends Activity {
- private GestureDetector gd; // 手势检测
- private GlobalUtil globalUtil; // 全局公用类
- private ScrollView scrollView; // 滚动视图
- private LinearLayout headerLayout, footerLayout; // 顶部、底部布局
- private TextView textView; // 文本标签
- private static final long ANIM_DURATION = 500; // 动画时间(毫秒)
- private static final int DIALOG_TEXT_LIST = 0; // 文本列表对话框id
- private final String[] textPaths = new String[] { "one.txt", "two.txt",
- "浏览..." }; // assets内文本资源路径
- protected String textTitle; // 文本标题
- protected String textContent; // 文本内容
- private Timer timer; // 计时器
- private static final long TIMEOUT = 2000; // 超时时间
- private static final int TIMER_LAYOUT_OUT = 1; // 布局收起
- private boolean isLayoutOut = false; // 布局收起状态
- /** Handler处理操作 */
- public Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case TIMER_LAYOUT_OUT:
- /* headerLayout收起动画 */
- globalUtil.startTransAnim(headerLayout,
- GlobalUtil.AnimMode.UP_OUT, ANIM_DURATION);
- headerLayout.setVisibility(View.GONE);
- /* footerLayout收起动画 */
- globalUtil.startTransAnim(footerLayout,
- GlobalUtil.AnimMode.DOWN_OUT, ANIM_DURATION);
- footerLayout.setVisibility(View.GONE);
- isLayoutOut = true; // 重置布局收起状态
- break;
- }
- }
- };
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- gd = new GestureDetector(new MySimpleGesture()); // 手势检测处理
- globalUtil = GlobalUtil.getInstance(); // 获取全局公用类
- scrollView = (ScrollView) findViewById(R.id.scrollView); // 获取滚动视图
- headerLayout = (LinearLayout) findViewById(R.id.headerLayout); // 获取顶部布局
- footerLayout = (LinearLayout) findViewById(R.id.footerLayout); // 获取底部布局
- textView = (TextView) findViewById(R.id.textView);
- setText(0); // 默认显示“上邪.txt”
- newTimerLayoutOut(); // 定时收起布局
- }
- /** 使用GestureDetector检测手势(ScrollView内也需监听时的方式) */
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- gd.onTouchEvent(ev);
- scrollView.onTouchEvent(ev);
- return super.dispatchTouchEvent(ev);
- }
- /** onCreateDialog */
- @Override
- protected Dialog onCreateDialog(int id) {
- switch (id) {
- case DIALOG_TEXT_LIST:
- return new AlertDialog.Builder(this).setItems(textPaths,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (2 == which) {
- // 跳转到文件浏览Activity
- startActivityForResult(new Intent(
- TtsFatherActivity.this,
- FileBrowserActivity.class),
- FileBrowserActivity.CODE_FILE_BROWSER);
- } else {
- setText(which); // 设置文本内容
- }
- }
- }).create();
- }
- return super.onCreateDialog(id);
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == FileBrowserActivity.CODE_FILE_BROWSER) {
- if (resultCode == RESULT_OK) {
- // 获得文件名称
- String filename = data.getExtras().getString(
- FileBrowserActivity.KEY_FILENAME);
- this.textTitle = filename;
- try {
- // FileInputStream fis = new FileInputStream(
- // new File(filename));
- // // FileInputStream不支持mark/reset操作,不该直接这样
- // String encoding = globalUtil.getIsEncoding(fis);
- // textContent = globalUtil.is2Str(fis, encoding);
- /**
- * TXT简单判断编码类型后转字符串
- *
- * ps:
- * 1)扯淡,3.58MB的txt读出来了==
- * 看来需要转成BufferedReader以readLine()方式读好些啊
- *
- * 2)TextView将大文本全部显示,这貌似...
- *
- * 时间主要花费在文本显示过程,不改进了,暂时将就吧==
- * 2.1)用View自定义个控件显示文本也蛮久的,未减少多少时间。
- * 2.2)至于AsyncTask,文本显示还是要在UI线程的==。
- *
- * 如果我们要仿个阅读器,用View自定义个控件还是必须的。
- * 1)分段读取大文本,可以考虑3段(前后两段用于缓冲)
- * 根据滑屏&显示内容等,注意文本显示衔接。
- * 2)滚动条可以外面套个ScrollView。由各属性判断出大文本需要显示的高度,
- * 重写onMeasure用setMeasuredDimension()设置好,才会有滚动条。
- * 当然自己用scrollTo()、scrollBy()实现动画也是好的。
- * 3)至于其他选中当前行啊什么的,慢慢写就成了...
- *
- * 不知道大家还有什么好的想法没?
- */
- // long time1 = System.currentTimeMillis();
- textContent = globalUtil.is2Str(new FileInputStream(
- new File(filename)));
- // long time2 = System.currentTimeMillis();
- // Log.e("TAG1", "==" + (time2 - time1) + "==");
- textView.setText(textContent);
- // long time3 = System.currentTimeMillis();
- // Log.e("TAG1", "==" + (time3 - time2) + "==");
- } catch (Exception e) {
- textView.setText(R.string.text_error);
- textContent = "";
- }
- }
- }
- }
- /** 设置文本内容 */
- private void setText(int textIndex) {
- this.textTitle = textPaths[textIndex];
- try {
- textContent = globalUtil.is2Str(getAssets().open(textTitle),
- "UTF-8");
- textView.setText(textContent);
- } catch (IOException e) {
- textView.setText(R.string.text_error);
- textContent = "";
- }
- }
- /** 定时收起布局(已定时时重新开始定时) */
- protected void newTimerLayoutOut() {
- if (null != timer) {
- timer.cancel();
- }
- timer = new Timer();
- // 超时TIMEOUT退出
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- mHandler.sendEmptyMessage(TIMER_LAYOUT_OUT);
- }
- }, TIMEOUT);
- }
- /** 自定义手势类 */
- private class MySimpleGesture extends SimpleOnGestureListener {
- /** 双击第二下 */
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- if (isLayoutOut) {
- /* headerLayout进入动画 */
- headerLayout.setVisibility(View.VISIBLE);
- globalUtil.startTransAnim(headerLayout,
- GlobalUtil.AnimMode.UP_IN, ANIM_DURATION);
- /* footerLayout进入动画 */
- footerLayout.setVisibility(View.VISIBLE);
- globalUtil.startTransAnim(footerLayout,
- GlobalUtil.AnimMode.DOWN_IN, ANIM_DURATION);
- newTimerLayoutOut(); // 定时收起布局
- isLayoutOut = false; // 重置布局收起状态
- } else {
- /* headerLayout退出动画 */
- globalUtil.startTransAnim(headerLayout,
- GlobalUtil.AnimMode.UP_OUT, ANIM_DURATION);
- headerLayout.setVisibility(View.GONE);
- /* footerLayout退出动画 */
- globalUtil.startTransAnim(footerLayout,
- GlobalUtil.AnimMode.DOWN_OUT, ANIM_DURATION);
- footerLayout.setVisibility(View.GONE);
- // 取消定时收起动画
- if (null != timer) {
- timer.cancel();
- }
- isLayoutOut = true; // 重置布局收起状态
- }
- return false;
- }
- /** 长按屏幕时 */
- @Override
- public void onLongPress(MotionEvent e) {
- // 显示文本列表对话框
- showDialog(DIALOG_TEXT_LIST);
- }
- }
- }
2)TTS控制
音量&语速控制也写了的^^。
TtsSampleActivity.java
- public class TtsSampleActivity extends TtsFatherActivity implements
- OnSeekBarChangeListener, TextToSpeech.OnInitListener,
- TextToSpeech.OnUtteranceCompletedListener {
- // private static final String TAG = "TtsSampleActivity"; // 日志标记
- private AudioManager audioManager; // 音频管理对象
- // TTS音量类型(AudioManager.STREAM_MUSIC = AudioManager.STREAM_TTS = 11)
- private static final int STREAM_TTS = AudioManager.STREAM_MUSIC;
- private TextToSpeech mTts; // TTS对象
- private static final int REQ_CHECK_TTS_DATA = 110; // TTS数据校验请求值
- private boolean isSetting = false; // 进入设置标记
- private boolean isRateChanged = false; // 速率改变标记
- private boolean isStopped = false; // TTS引擎停止发声标记
- private float mSpeechRate = 1.0f; // 朗读速率
- private SeekBar volumeBar, speedBar; // 音量&语速
- // 合成声音资源文件的路径
- private static final String SAVE_DIR_PATH = "/sdcard/AndroidTTS/";
- private static final String SAVE_FILE_PATH = SAVE_DIR_PATH + "sound.wav";
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 获得音频管理对象
- audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- /* volumeBar */
- volumeBar = (SeekBar) findViewById(R.id.volumeBar);
- volumeBar.setOnSeekBarChangeListener(this);
- // 由当前音量设置进度(需保证进度上限=音频上限=15,否则按比例设置)
- volumeBar.setProgress(audioManager.getStreamVolume(STREAM_TTS));
- /* speedBar */
- speedBar = (SeekBar) findViewById(R.id.speedBar);
- speedBar.setOnSeekBarChangeListener(this);
- initDirs(SAVE_DIR_PATH); // 初始化文件夹路径
- }
- /** saveFileBtn点击事件 */
- public void saveFile(View v) {
- // 将文本合成声音资源文件
- int resId = TextToSpeech.SUCCESS == ttsSaveFile(textContent,
- SAVE_FILE_PATH) ? R.string.synt_success : R.string.synt_fail;
- Toast.makeText(this, resId, Toast.LENGTH_SHORT).show(); // Toast提示
- newTimerLayoutOut(); // 重新定时收起布局
- }
- /** playFileBtn点击事件 */
- public void playFile(View v) {
- ttsPlayFile(SAVE_FILE_PATH); // 播放指定的使用文件
- newTimerLayoutOut(); // 重新定时收起布局
- }
- /** stopBtn点击事件 */
- public void stop(View v) {
- ttsStop(); // 停止当前发声
- newTimerLayoutOut(); // 重新定时收起布局
- }
- /** playBtn点击事件 */
- public void play(View v) {
- ttsPlay(); // tts合成语音播放
- newTimerLayoutOut(); // 重新定时收起布局
- }
- /** settingBtn点击事件 */
- public void setting(View v) {
- // 跳转到“语音输入与输出”设置界面&设置标志位
- isSetting = toTtsSettings();
- newTimerLayoutOut(); // 重新定时收起布局
- }
- /** SeekBar进度改变时 */
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- switch (seekBar.getId()) {
- case R.id.volumeBar:
- // 由设置当前TTS音量(需保证进度上限=音频上限=15,否则按比例设置)
- audioManager.setStreamVolume(STREAM_TTS, progress, 0);
- break;
- case R.id.speedBar:
- /* 需要重新绑定TTS引擎,速度在onInit()里设置 */
- isRateChanged = true; // 速率改变标记
- // 最大值为20时,以下方式计算为0.5~2倍速
- mSpeechRate = (progress >= 10) ? (progress / 10f)
- : (0.5f + progress / 20f);
- // 校验TTS引擎安装及资源状态,重新绑定引擎
- checkTtsData();
- break;
- }
- newTimerLayoutOut(); // 重新定时收起布局
- }
- /** SeekBar开始拖动时 */
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
- /** SeekBar结束拖动时 */
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
- /**
- * TTS引擎初始化时回调方法
- *
- * 引擎相关参数(音量、语速)等都需在这设置。
- * 1)创建完成后再去设置,会有意外的效果^^
- * 2)音量也可由AudioManager进行控制(和音乐一个媒体流类型)
- */
- @Override
- public void onInit(int status) {
- if (status == TextToSpeech.SUCCESS) {
- mTts.setSpeechRate(mSpeechRate); // 设置朗读速率
- // 设置发声合成监听,注意也需要在onInit()中做才有效
- mTts.setOnUtteranceCompletedListener(this);
- if (isRateChanged) {
- ttsPlay(); // tts合成语音播放
- isRateChanged = false; // 重置标记位
- }
- }
- }
- /**
- * TTS引擎完成发声完成时回调方法
- *
- * 1)stop()取消时也会回调
- * 2)需在onInit()内设置接口
- * 3)utteranceId由speak()时的请求参数设定
- * 参数key:TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID
- */
- @Override
- public void onUtteranceCompleted(final String utteranceId) {
- /* 测试该接口的Toast提示 */
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- int resId = isStopped ? R.string.utte_stopped
- : R.string.utte_completed;
- // 提示文本发生完成
- Toast.makeText(getApplicationContext(),
- getString(resId, utteranceId), Toast.LENGTH_SHORT)
- .show();
- }
- });
- }
- /** onActivityResult */
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == REQ_CHECK_TTS_DATA) {
- switch (resultCode) {
- case TextToSpeech.Engine.CHECK_VOICE_DATA_PASS: // TTS引擎可用
- // 针对于重新绑定引擎,需要先shutdown()
- if (null != mTts) {
- ttsStop(); // 停止当前发声
- ttsShutDown(); // 释放资源
- }
- mTts = new TextToSpeech(this, this); // 创建TextToSpeech对象
- break;
- case TextToSpeech.Engine.CHECK_VOICE_DATA_BAD_DATA: // 数据错误
- case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA: // 缺失数据资源
- case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_VOLUME: // 缺少数据存储量
- notifyReinstallDialog(); // 提示用户是否重装TTS引擎数据的对话框
- break;
- case TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL: // 检查失败
- default:
- break;
- }
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
- /** 校验TTS引擎安装及资源状态 */
- private boolean checkTtsData() {
- try {
- Intent checkIntent = new Intent();
- checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
- startActivityForResult(checkIntent, REQ_CHECK_TTS_DATA);
- return true;
- } catch (ActivityNotFoundException e) {
- return false;
- }
- }
- /** 提示用户是否重装TTS引擎数据的对话框 */
- private void notifyReinstallDialog() {
- new AlertDialog.Builder(this).setTitle("TTS引擎数据错误")
- .setMessage("是否尝试重装TTS引擎数据到设备上?")
- .setPositiveButton("是", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // 触发引擎在TTS引擎在设备上安装资源文件
- Intent dataIntent = new Intent();
- dataIntent
- .setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
- startActivity(dataIntent);
- }
- }).setNegativeButton("否", null).show();
- }
- /** 跳转到“语音输入与输出”设置界面 */
- private boolean toTtsSettings() {
- try {
- startActivity(new Intent("com.android.settings.TTS_SETTINGS"));
- return true;
- } catch (ActivityNotFoundException e) {
- return false;
- }
- }
- @Override
- protected void onStart() {
- checkTtsData(); // 校验TTS引擎安装及资源状态
- super.onStart();
- }
- @Override
- protected void onResume() {
- /* 从设置返回后重新绑定TTS,避免仍用旧引擎 */
- if (isSetting) {
- checkTtsData(); // 校验TTS引擎安装及资源状态
- isSetting = false;
- }
- super.onResume();
- }
- @Override
- protected void onStop() {
- /* HOME键 */
- ttsStop(); // 停止当前发声
- super.onStop();
- }
- @Override
- public void onBackPressed() {
- /* BACK键 */
- ttsStop(); // 停止当前发声
- ttsShutDown(); // 释放资源
- super.onBackPressed();
- }
- /** tts合成语音播放 */
- private int ttsPlay() {
- if (null != mTts) {
- isStopped = false; // 设置标记
- /**
- * 叙述text。
- *
- * 1) 参数2(int queueMode)
- * 1.1)QUEUE_ADD:增加模式。增加在队列尾,继续原来的说话。
- * 1.2)QUEUE_FLUSH:刷新模式。中断正在进行的说话,说新的内容。
- * 2)参数3(HashMap<String, String> params)
- * 2.1)请求的参数,可以为null。
- * 2.2)注意KEY_PARAM_UTTERANCE_ID。
- */
- HashMap<String, String> params = new HashMap<String, String>();
- params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, textTitle);
- return mTts.speak(textContent, TextToSpeech.QUEUE_FLUSH, params);
- }
- return TextToSpeech.ERROR;
- }
- // /** 判断TTS是否正在发声 */
- // private boolean isSpeaking() {
- // // 使用mTts.isSpeaking()判断时,第一次speak()返回true,多次就返回false了。
- // return audioManager.isMusicActive();
- // }
- /** 停止当前发声,同时放弃所有在等待队列的发声 */
- private int ttsStop() {
- isStopped = true; // 设置标记
- return (null == mTts) ? TextToSpeech.ERROR : mTts.stop();
- }
- /** 释放资源(解除语音服务绑定) */
- private void ttsShutDown() {
- if (null != mTts) {
- mTts.shutdown();
- }
- }
- /** 初始化文件夹路径 */
- private void initDirs(final String dirpath) {
- File file = new File(dirpath);
- if (!file.exists()) {
- file.mkdirs();
- }
- }
- /** 将文本合成声音资源文件 */
- private int ttsSaveFile(String text, final String filename) {
- return (null == mTts) ? TextToSpeech.ERROR : mTts.synthesizeToFile(
- text, null, filename);
- }
- /** 播放指定的使用文件 */
- private int ttsPlayFile(final String filename) {
- // 如果存在FILENAME_SAVE文件的话
- if (new File(filename).exists()) {
- try {
- /* 使用MediaPlayer进行播放(没进行控制==) */
- MediaPlayer player = new MediaPlayer();
- player.setDataSource(filename);
- player.prepare();
- player.start();
- return TextToSpeech.SUCCESS;
- } catch (Exception e) {
- e.printStackTrace();
- return TextToSpeech.ERROR;
- }
- }
- return TextToSpeech.ERROR;
- }
- }
3)公共工具
这个也贴出来吧==。
GlobalUtil.java
- /**
- * @brief 全局公用类
- * @details 各部分公用内容都较少,就丢一起了==。
- */
- public final class GlobalUtil {
- /** Bob Lee懒加载:内部类GlobalUtilHolder */
- static class GlobalUtilHolder {
- static GlobalUtil instance = new GlobalUtil();
- }
- /** Bob Lee懒加载:返回GlobalUtil的单例 */
- public static GlobalUtil getInstance() {
- return GlobalUtilHolder.instance;
- }
- /** 获取窗口默认显示信息 */
- public Display getDisplay(Context mContext) {
- WindowManager wm = (WindowManager) mContext
- .getSystemService(Context.WINDOW_SERVICE);
- return wm.getDefaultDisplay();
- }
- /** 动画方式 */
- public enum AnimMode {
- UP_IN, UP_OUT, DOWN_IN, DOWN_OUT, LEFT_IN, LEFT_OUT, RIGHT_IN, RIGHT_OUT
- };
- /**
- * @brief 横移或竖移动画
- *
- * @param v 移动视图
- * @param animMode 动画方式
- * @param durationMillis 持续时间
- */
- public void startTransAnim(View v, AnimMode animMode, long durationMillis) {
- int w = v.getWidth(), h = v.getHeight(); // 获取移动视图宽高
- float fromXDelta = 0, toXDelta = 0, fromYDelta = 0, toYDelta = 0;
- switch (animMode) {
- case UP_IN:
- fromYDelta = -h;
- break;
- case UP_OUT:
- toYDelta = -h;
- break;
- case DOWN_IN:
- fromYDelta = h;
- break;
- case DOWN_OUT:
- toYDelta = h;
- break;
- case LEFT_IN:
- fromXDelta = -w;
- break;
- case LEFT_OUT:
- toXDelta = -w;
- break;
- case RIGHT_IN:
- fromXDelta = w;
- break;
- case RIGHT_OUT:
- toXDelta = w;
- break;
- }
- TranslateAnimation transAnim = new TranslateAnimation(fromXDelta,
- toXDelta, fromYDelta, toYDelta); // 位移动画
- transAnim.setDuration(durationMillis); // 设置时间
- v.startAnimation(transAnim); // 开始动画
- }
- /**
- * @brief InputStream转为String
- *
- * @param is 输入流
- * @param encoding 编码方式
- * @return 字符串结果
- * @throws UnsupportedEncodingException 不支持的编码
- */
- public String is2Str(InputStream is, String encoding)
- throws UnsupportedEncodingException {
- /*
- * 不直接从InputStream里读byte[],再转成String,以避免截断汉字。
- * 如utf8一个汉字3字节,用byte[1024]会截断末尾而乱码。
- */
- InputStreamReader isReader = new InputStreamReader(is, encoding);
- /* 以char[]方式读取 */
- StringBuffer out = new StringBuffer();
- try {
- char[] b = new char[4096]; // 1024*4*2Byte
- for (int n; (n = isReader.read(b)) != -1;) {
- out.append(b, 0, n);
- }
- return out.toString();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
- /**
- * @brief 带BOM的文本的FileInputStream转为String,自动判断编码类型
- *
- * @param fis 文件输入流
- * @return 字符串结果
- * @throws UnsupportedEncodingException 不支持的编码
- */
- public String is2Str(FileInputStream fis)
- throws UnsupportedEncodingException {
- // 转成BufferedInputStream
- BufferedInputStream bis = new BufferedInputStream(fis);
- // 简单判断文本编码
- String encoding = getIsEncoding(bis);
- // 转成BufferedReader
- BufferedReader reader = new BufferedReader(new InputStreamReader(bis,
- encoding));
- /* 以readLine()方式读取 */
- StringBuffer out = new StringBuffer();
- try {
- for (String s; (s = reader.readLine()) != null;) {
- out.append(s);
- out.append("\n");
- }
- return out.toString();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
- /**
- * @brief 带BOM的文本判断,否则认为GB2312(即ANSI类型的TXT)
- * @details 复杂文件编码检测,请google cpdetector!
- *
- * @param is InputStream
- * @return 编码类型
- *
- * @warning markSupported为true时才进行判断,否则返回默认GB2312。
- * \n FileInputStream不支持mark/reset操作;BufferedInputStream支持此操作。
- */
- public String getIsEncoding(InputStream is) {
- String code = "GB2312";
- // Log.e("is.markSupported()", "==" + is.markSupported() + "==");
- if (is.markSupported()) { // 支持mark()
- try {
- is.mark(5); // 打个TAG(5>3)
- byte[] head = new byte[3];
- is.read(head);
- if (head[0] == -1 && head[1] == -2)
- code = "UTF-16";
- if (head[0] == -2 && head[1] == -1)
- code = "Unicode";
- if (head[0] == -17 && head[1] == -69 && head[2] == -65)
- code = "UTF-8";
- is.reset(); // 返回TAG
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return code;
- }
- }
四、阅读器截图
1)进入画面.png
2)长按屏幕.png
3)自带two.txt.png
4)“浏览…操作”的截图
浏览...(1).png
浏览...(2).png
浏览...(3).png
五、后记
直接读大文本,后果自负啊。(没做控制呢T^T)
附件下载:
作者:winorlose2000
- Android简单阅读器.zip (148.8 KB)
- 下载次数: 5
- 讯飞TTS主程序及语音包.rar (6 MB)
- 下载次数: 1
发表评论
-
android.os.NetworkOnMainThreadException 异常处理
2015-03-13 16:19 518http://www.cnblogs.com/freexia ... -
Android 访问权限设置
2015-03-13 16:19 439Android开发应用程序时,如果应用程序需要访问网络权限, ... -
Android 获取唯一机器码的代码
2015-03-13 16:18 1174做应用时很多时候都得获取到每个设备的机器码 Secu ... -
获取android手机基本信息
2015-03-13 14:03 659http://zdpeng.iteye.com/blog/1 ... -
java发送http的get、post请求
2015-03-13 13:59 589http://www.cnblogs.com/zhuawa ... -
浅析android应用增量升级
2015-01-06 10:31 620http://blog.csdn.net/hmg25/ ... -
Android App应用包增量升级(one)
2015-01-06 10:29 1059http://kinggoo.com/bsdiffupdat ... -
Android 增量更新实例(Smart App Updates)
2015-01-06 10:28 608http://892848153.iteye.com/blo ... -
常用的android弹出对话框
2014-04-15 09:34 532http://blog.csdn.net/wei_ge163 ... -
Android滑动手势侦测方法介绍
2013-07-06 17:19 781http://developer.51cto.com/art ... -
Android开发工具之DDMS
2013-06-24 13:52 867http://www.cnblogs.com/jerrych ... -
Android 程序自动更新功能模块实现
2013-06-20 11:42 931Android 程序自动更新功能模块实现 在程 ... -
Android之远程图片获取和本地缓存
2013-06-15 07:11 723http://www.cnblogs.com/top5 ... -
Android 利用缓存机制实现文件下载
2013-06-15 07:08 1407http://www.cctime.com/html/20 ... -
Android学习系列--App缓存管理
2013-06-15 06:58 583http://www.cnblogs.com/qianxud ... -
Android中Bitmap缓存池
2013-06-12 22:28 693http://mobile.51cto.com/andr ... -
android之调用webservice实现图片上传
2013-03-24 11:41 1084http://www.cnblogs.com/top5/ar ... -
Android中的Selector的用法
2013-03-21 15:44 636作者原文地址:http://blog.csdn.net/s ... -
Android中的Binder机制
2013-03-20 19:21 787来自:http://www.cnblogs.com/inno ... -
Android中的Handler机制
2013-03-20 19:17 637来自: http://www.cnblogs.com/ke ...
相关推荐
android下实现对文本的语音朗读,TTS技术,支持中文朗读。Android SDK 4.04下测试通过。 附件包含测试源代码及语音库文件 这是语音合成测试工程,如果需要朗读中文请安装中文引擎。我采用的是讯飞语音库,手机版本...
在Android应用开发中,可以利用Samsung的TTS引擎来创建功能丰富的中文语音阅读器,读取并播放TXT文本文件的内容。 要实现这样的功能,开发者首先需要在Android项目中集成Samsung的TTS引擎库。这通常涉及在build....
在Android平台上,开发一款类似iReader的阅读器应用是一项具有挑战性和创新性的任务。iReader作为知名的电子书阅读软件,以其简洁的界面、流畅的翻页效果和丰富的功能深受用户喜爱。下面我们将深入探讨如何构建这样...
在Android平台上,Text-to-Speech(TTS)技术是一种将文本转换为语音输出的功能,它使得应用程序能够“读出”屏幕上的文字,这对于视力障碍的用户或者在不方便阅读时非常有用。本项目“基于Android的TTs”显然是一个...
标题 "delphi_xe5_android_tts(Text_To_Speech).ZIP" 暗示这是一个使用Embarcadero Delphi XE5开发的项目,专注于在Android平台上实现文本转语音(TTS,Text-to-Speech)功能。Delphi是面向对象的 Pascal 编程语言的...
Android的文本转语音(Text-to-Speech,简称TTS)技术是一种将文本数据转换为可听见的语音输出的系统,广泛应用于各种应用中,如阅读器、导航、语音助手等。在Android Studio环境下,开发者可以方便地利用Android...
在Android平台上,TTS技术的应用非常广泛,比如阅读辅助应用、导航软件中的语音播报功能等。TTS引擎可以将任何文本内容转化为语音输出,方便用户在无法查看屏幕的情况下获取信息。 #### 二、Android TTS框架介绍 ...
Android的TextToSpeech类是实现TTS的主要接口,它提供了将文本转化为可听见的语音的功能。开发者可以通过这个类来控制语音的发音速度、音调、语调等属性。 **2. 初始化TextToSpeech** 在使用TTS之前,首先需要实例...
在Android平台上实现中文转语音,通常需要集成第三方的TTS引擎,因为Android自带的TTS引擎可能不支持所有语言,包括中文。 集成手说语音库是实现中文TTS的一种常见方法。手说语音库提供了高质量的中文发音,支持...
在Android系统中,TTS引擎可以通过设置和API调用来集成到各种应用程序中,例如阅读器、导航应用、教育软件等,为用户提供语音反馈和互动。 在压缩包内的“Speechcloud”可能是指科大讯飞的云端语音服务,虽然未提供...
Android电子束阅读器是一款专为Android操作系统设计的电子书阅读应用程序。它允许用户在移动设备上轻松地阅读、管理和组织各种格式的电子书籍。这款应用通常支持常见的电子书格式,如EPUB、PDF、MOBI、AZW3等,旨在...
这个项目提供了实现Android TTS功能的完整代码示例,可以帮助开发者了解如何在自己的应用中集成TTS。下面我们将深入探讨Android TTS的关键知识点: 1. **初始化TTS引擎**:在Android中,我们需要实例化`TextTo...
在Android平台上,文本转语音(Text To Speech, TTS)是一项重要的功能,它允许应用程序将文字内容转化为可听见的语音输出。这对于视力障碍者、学习语言的用户或者在驾驶等不便阅读场景下的用户来说非常实用。本文将...
在Android系统中,TTS功能可以帮助开发者创建能够读出文字信息的应用,尤其适用于阅读障碍者、视力不佳的用户或者在驾驶、做家务等不便看屏幕的场景。本工程实例提供了如何在Android平台上集成和使用中文语言包的...
在这个“Android文字转语音(TTS)简单例子”中,我们将探讨如何集成和使用Android的TTS服务来实现文字到语音的转换。 首先,要使用Android的TTS服务,我们需要在AndroidManifest.xml文件中添加必要的权限: ```...
在Android SDK 1.6中,Text-to-Speech (TTS)是一项重要的新特性,它允许应用程序将文本转化为不同语言的语音输出,极大地提升了用户体验。本文将深入解析TTS API的使用方法及其在实际项目中的应用。 首先,TTS引擎...
【时事新闻阅读器】是一款专为Android手机用户设计的新闻阅读应用,它结合了现代科技与信息获取的便利性,让阅读新闻变得更加轻松愉快。该应用的核心功能是通过语音朗读的方式,让用户在忙碌或者不便操作手机的情况...