




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于OPhone SDK1.5的英文电子词典的实现OPhone平台开发, 2009-12-07 11:06:42 标签 : OPhone SDK1.5 英文词典 英文词典是手机中经常使用的应用。因此,在本文将结合中国移动最新的OPhone SDK1.5来讨论如何实现一个OPhone版的英文词典。实现英文词典的方法很多。在本文使用了SQLite数据库来保存英文单词信息。系统通过SQLite数据库中保存的单词信息来查找到与指定英文对应的中文信息。当然,实现这样一个英文词典需要解决一系列技术问题。例如,如何将保存英文单词信息的数据库文件随程序(apk文件)一起发布;发布后如何打开数据库;如何在输入前几个字母后,在AutoCompleteTextView组件提示列表中显示以所输入字符串开头的所有单词。在本章将逐渐给出这些问题的详细答案。 关于本文实现的英文电子词典的完整代码请读者参本文提供的源代码。 电子词典的程序结构 本文实现的电子词典可以从数据库中查找单词的中文解释。程序的界面由一个AutoCompleteTextView和一个Button组成,这两个组件在main.xml文件中定义,代码如下:view plaincopy to clipboardprint?1. 2. 5. 8. 10. 在系统中只有一个Main类,负责处理电子词典的所有功能。在该类的onCreate方法中装载了main.xml文件。 如何建立SQLite数据库 在本例中提供了一个dictionary.db数据库文件,该数据库中包含了一个t_words表,在这个表中保存了英文单词的相关信息。但这个数据库是事先建立的,在本节将介绍一下如何在PC上建立这个数据库文件及t_words表。SQLite数据库是一个开源免费的数据库,支持多种数据库接口。Ophone系统正是使用了这种数据库作为其优秀的数据存储方案。建立SQLite数据库的工具很多,例如,SQlite官方提供了一个控制台程序,可以建立并维护SQLite数据库工具,读者可以从如下的地址下载这个控制台程序:/download.html 目前这个程序的最新版本是3.6.2,读者可以下载Sqlite-3_6_20.zip文件,解压后只有一个sqlite3.exe文件,启动这个文件,即可进入控制台界面。 如果想建立一个数据库,只需要输入如下命令即可:view plaincopy to clipboardprint?1. sqlite3.exedictionary.dbsqlite3.exe dictionary.db 这时控制台程序还不会立即生成dictionary.db文件,直到输入一条与数据库相关的命令后,才会在当前目录生成一个dictionary.db,例如,输入如下的SQL语句建立一个表:view plaincopy to clipboardprint?1. createtabletable1( 2. idintegerprimarykey, 3. ageint, 4. nametext 5. );create table table1 ( id integer primary key, age int, name text );虽然sqlite3.exe可以很容易地生成并管理数据库,但毕竟是控制台程序,使用起来很不方便。因此,在这里作者介绍一种可视化的管理SQLite数据库的工具:SQLite Expert Professional。这种工具有些类似于SQL Server的企业管理器,可以可视化地建立数据库、表、视图等数据库组件。SQLite Expert Professional的主界面。 读者可以从如下的地址下载SQLite Expert Professional。/ 下面我们来使用SQLite Expert Professional建立一个dictionary.db数据库,并建立一个t_words表,结果如图5所示。通过图5中的Design标签页可以修改t_words表的结构,例如,添加、删除字段等。从图5所示的表结构可以看出,t_words有两个字段:english和chinese,分别用来保存英文单词和中文解释信息。最后就需要我们向t_words表中添加等查找的单词信息了。至于这些信息,读者可以在网上查找或自己输入,在本例中只提供了大学英语4级(CET4)的大纲词汇。由于本文的目的只是介绍如何编写一个基于OPhone SDK1.5的电子词典,因此,关于t_words表中实际的英文单词信息读者可以根据自己的需要添加。 如何处理电子词典中的数据库文件在上一节已经介绍了如何建立本例所使用的dictionary.db数据库和t_words表,那么在建立完dictionary.db数据库文件,并添加相应的数据后,需要将这个文件放在Eclipse工程的resraw目录中与apk文件一起发布。但在这里有一个问题。就是这个数据库文件被放在了resraw目录中同apk文件一起发布。那么如何在安装apk后打开并使用这个数据库文件呢? OPhone SDK不能直接打开resraw目录中的数据库文件,不过我们可以通过将这个文件复制到手机内存或SD卡上来访问。复制的方法也很简单,就是在程序第一次启动时判断要复制的目标路径是否存在该数据库文件,如果不存在该数据库文件,那先复制这个文件,然后再打开数据库文件。 复制数据库文件可以通过getResources().openRawResource方法获得resraw目录中资源的InputStream对象,然后将该InputStream对象中的数据写入其他的目录中相应文件中。打开数据库可以使用SQLiteDatabase.openOrCreateDatabase方法来打开SQLite数据库文件。openOrCreateDatabase方法可以打开任意目录下的数据库文件。 复制和打开数据库文件的工作由openDatabase方法来完成,这个方法的完整代码如下:view plaincopy to clipboardprint?1. 2. 5. 8. 10. 在系统中只有一个Main类,负责处理电子词典的所有功能。在该类的onCreate方法中装载了main.xml文件,装载后的效果如图1所示。在界面上方的文本框中可以输入要查找的单词,如图2所示。 如何建立SQLite数据库 在本例中提供了一个dictionary.db数据库文件,该数据库中包含了一个t_words表,在这个表中保存了英文单词的相关信息。但这个数据库是事先建立的,在本节将介绍一下如何在PC上建立这个数据库文件及t_words表。SQLite数据库是一个开源免费的数据库,支持多种数据库接口。Ophone系统正是使用了这种数据库作为其优秀的数据存储方案。建立SQLite数据库的工具很多,例如,SQlite官方提供了一个控制台程序,可以建立并维护SQLite数据库工具,读者可以从如下的地址下载这个控制台程序:/download.html 目前这个程序的最新版本是3.6.2,读者可以下载Sqlite-3_6_20.zip文件,解压后只有一个sqlite3.exe文件,启动这个文件,即可进入控制台界面。如图3所示。 如果想建立一个数据库,只需要输入如下命令即可:view plaincopy to clipboardprint?1. sqlite3.exedictionary.dbsqlite3.exe dictionary.db 这时控制台程序还不会立即生成dictionary.db文件,直到输入一条与数据库相关的命令后,才会在当前目录生成一个dictionary.db,例如,输入如下的SQL语句建立一个表:view plaincopy to clipboardprint?1. createtabletable1( 2. idintegerprimarykey, 3. ageint, 4. nametext 5. );create table table1 ( id integer primary key, age int, name text );虽然sqlite3.exe可以很容易地生成并管理数据库,但毕竟是控制台程序,使用起来很不方便。因此,在这里作者介绍一种可视化的管理SQLite数据库的工具:SQLite Expert Professional。这种工具有些类似于SQL Server的企业管理器,可以可视化地建立数据库、表、视图等数据库组件。SQLite Expert Professional的主界面如图4所示。 读者可以从如下的地址下载SQLite Expert Professional。/ 下面我们来使用SQLite Expert Professional建立一个dictionary.db数据库,并建立一个t_words表,结果如图5所示。通过图5中的Design标签页可以修改t_words表的结构,例如,添加、删除字段等。从图5所示的表结构可以看出,t_words有两个字段:english和chinese,分别用来保存英文单词和中文解释信息。最后就需要我们向t_words表中添加等查找的单词信息了。至于这些信息,读者可以在网上查找或自己输入,在本例中只提供了大学英语4级(CET4)的大纲词汇。由于本文的目的只是介绍如何编写一个基于Ophone SDK1.5的电子词典,因此,关于t_words表中实际的英文单词信息读者可以根据自己的需要添加。 如何处理电子词典中的数据库文件 在上一节已经介绍了如何建立本例所使用的dictionary.db数据库和t_words表,那么在建立完dictionary.db数据库文件,并添加相应的数据后,需要将这个文件放在Eclipse工程的resraw目录中与apk文件一起发布。但在这里有一个问题。就是这个数据库文件被放在了resraw目录中同apk文件一起发布。那么如何在安装apk后打开并使用这个数据库文件呢? Ophone SDK不能直接打开resraw目录中的数据库文件,不过我们可以通过将这个文件复制到手机内存或SD卡上来访问。复制的方法也很简单,就是在程序第一次启动时判断要复制的目标路径是否存在该数据库文件,如果不存在该数据库文件,那先复制这个文件,然后再打开数据库文件。 复制数据库文件可以通过getResources().openRawResource方法获得resraw目录中资源的InputStream对象,然后将该InputStream对象中的数据写入其他的目录中相应文件中。打开数据库可以使用SQLiteDatabase.openOrCreateDatabase方法来打开SQLite数据库文件。openOrCreateDatabase方法可以打开任意目录下的数据库文件。 复制和打开数据库文件的工作由openDatabase方法来完成,这个方法的完整代码如下:view plaincopy to clipboardprint?1. privateSQLiteDatabaseopenDatabase() 2. 3. try4. 5. /获得dictionary.db文件的绝对路径 6. StringdatabaseFilename=DATABASE_PATH+/+DATABASE_FILENAME; 7. Filedir=newFile(DATABASE_PATH); 8. /如果/sdcard/dictionary目录中存在,创建这个目录 9. if(!dir.exists() 10. dir.mkdir(); 11. /如果在/sdcard/dictionary目录中不存在 12. /dictionary.db文件,则从resraw目录中复制这个文件到 13. /SD卡的目录(/sdcard/dictionary) 14. if(!(newFile(databaseFilename).exists() 15. 16. /获得封装dictionary.db文件的InputStream对象 17. InputStreamis=getResources().openRawResource(R.raw.dictionary); 18. FileOutputStreamfos=newFileOutputStream(databaseFilename); 19. bytebuffer=newbyte8192; 20. intcount=0; 21. /开始复制dictionary.db文件 22. while(count=is.read(buffer)0) 23. 24. fos.write(buffer,0,count); 25. 26. 27. fos.close(); 28. is.close(); 29. 30. /打开/sdcard/dictionary目录中的dictionary.db文件 31. SQLiteDatabasedatabase=SQLiteDatabase.openOrCreateDatabase( 32. databaseFilename,null); 33. returndatabase; 34. 35. catch(Exceptione) 36. 37. 38. returnnull; 39. private SQLiteDatabase openDatabase() try / 获得dictionary.db文件的绝对路径 String databaseFilename = DATABASE_PATH + / + DATABASE_FILENAME; File dir = new File(DATABASE_PATH); / 如果/sdcard/dictionary目录中存在,创建这个目录 if (!dir.exists() dir.mkdir(); / 如果在/sdcard/dictionary目录中不存在 / dictionary.db文件,则从resraw目录中复制这个文件到 / SD卡的目录(/sdcard/dictionary) if (!(new File(databaseFilename).exists() / 获得封装dictionary.db文件的InputStream对象 InputStream is = getResources().openRawResource(R.raw.dictionary); FileOutputStream fos = new FileOutputStream(databaseFilename); byte buffer = new byte8192; int count = 0; / 开始复制dictionary.db文件 while (count = is.read(buffer) 0) fos.write(buffer, 0, count); fos.close(); is.close(); / 打开/sdcard/dictionary目录中的dictionary.db文件 SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase( databaseFilename, null); return database; catch (Exception e) return null; 在openDatabase方法中使用了几个常量,这些常量是在程序的主类(Main)中定义的,代码如下:view plaincopy to clipboardprint?1. publicclassMainextendsActivityimplementsOnClickListener,TextWatcher 2. 3. privatefinalStringDATABASE_PATH=android.os.Environment 4. .getExternalStorageDirectory().getAbsolutePath() 5. +/dictionary; 6. privatefinalStringDATABASE_FILENAME=dictionary.db; 7. . 8. public class Main extends Activity implements OnClickListener, TextWatcher private final String DATABASE_PATH = android.os.Environment .getExternalStorageDirectory().getAbsolutePath() + /dictionary; private final String DATABASE_FILENAME = dictionary.db; . . 从DATABASE_PATH常量可以看出,本系统将dictionary.db文件复制到了/sdcard/dictionary目录中,复制的结果如图6所示。 在本节的最后,我们看一看如何在Main类的onCreate方法的实现,在这个方法中调用了openDatabase方法来打开SD卡上的数据库,并完成了一些组件的装载和事件的绑定工作,代码如下:view plaincopy to clipboardprint?1. publicvoidonCreate(BundlesavedInstanceState) 2. 3. super.onCreate(savedInstanceState); 4. setContentView(R.layout.main); 5. /打开数据库,database是在Main类中定义的一个SQLiteDatabase类型的变量 6. database=openDatabase(); 7. /下面的代码装载了相关组件,并设置了相应的事件 8. btnSelectWord=(Button)findViewById(R.id.btnSelectWord); 9. actvWord=(AutoCompleteTextView)findViewById(R.id.actvWord); 10. btnSelectWord.setOnClickListener(this); 11. actvWord.addTextChangedListener(this); 12. public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); / 打开数据库,database是在Main类中定义的一个SQLiteDatabase类型的变量 database = openDatabase(); / 下面的代码装载了相关组件,并设置了相应的事件 btnSelectWord = (Button) findViewById(R.id.btnSelectWord); actvWord = (AutoCompleteTextView) findViewById(R.id.actvWord); btnSelectWord.setOnClickListener(this); actvWord.addTextChangedListener(this); 查询单词 下面来看看在英文词典中如何查找单词。查找单词的工作由【查单词】按钮的onClick事件方法完成,先看看这个方法的代码。view plaincopy to clipboardprint?1. publicvoidonClick(Viewview) 2. 3. /查找单词的SQL语句 4. Stringsql=selectchinesefromt_wordswhereenglish=?; 5. Cursorcursor=database.rawQuery(sql,newString 6. actvWord.getText().toString(); 7. Stringresult=未找到该单词.; 8. /如果查找单词,显示其中文信息 9. if(cursor.getCount()0) 10. 11. /必须使用moveToFirst方法将记录指针移动到第1条记录的位置 12. cursor.moveToFirst(); 13. result=cursor.getString(cursor.getColumnIndex(chinese); 14. 15. /显示查询结果对话框 16. newAlertDialog.Builder(this).setTitle(查询结果).setMessage(result) 17. .setPositiveButton(关闭,null).show(); 18. 19. public void onClick(View view) / 查找单词的SQL语句 String sql = select chinese from t_words where english=?; Cursor cursor = database.rawQuery(sql, new String actvWord.getText().toString() ); String result = 未找到该单词.; / 如果查找单词,显示其中文信息 if (cursor.getCount() 0) / 必须使用moveToFirst方法将记录指针移动到第1条记录的位置 cursor.moveToFirst(); result = cursor.getString(cursor.getColumnIndex(chinese); / 显示查询结果对话框 new AlertDialog.Builder(this).setTitle(查询结果).setMessage(result) .setPositiveButton(关闭, null).show(); 讲到这里我们应该了解一下dictionary.db中的t_words表的结果,该表只有两个字段:english和chinese。分别表示单词的英文和中文描述。如果要获得单词的中文描述,只需要查找chinese字段即可。如onClick方法中的代码所示。 查询单词的效果如图7所示。 如何使查找单词更智能化 虽然到现在为止,我们的英文词典已经可以正常工作了。但我们的探索精神是无止境的。大家可以想象,如果某位用户要查找一个单词,却突然想不起来这个单词的完整拼写了,而只记得单词的前面几个字母,那该怎么办呢? 也许有很多读者用过很多有查找功能的系统,其中Google搜索就是其中之一。只要输入一些要查找的字符串,Google搜索框就会为我们列出以这些输入串开头的经常使用到的搜索字符串,如图8所示。 实际上,这样的功能使用Ophone SDK也很容易实现。在电子词典中之所以使用AutoCompleteTextView组件输入单词就是为了达到这个目的。AutoCompleteTextView类有一个setAdapter方法,可以将一个Adapter对象绑定到AutoCompleteTextView组件中,一但在AutoCompleteTextView组件中输入两个及以上字母后,AutoCompleteTextView组件就会在这个绑定的Adapter对象中查找以所输入的字符串开头的单词,并显示在AutoCompleteTextView组件下方的列表中。效果如图9所示。 通过这个的方法,即使用户只记得单词的头几个字母,也可以查找这个单词的完整拼写形式。关于实现这个功能的详细过程,请读者看一下节的介绍。 如何显示以输入字符串开头的单词列表 由于Adapter对象既可以从数组、List等对象中获得数据,又可以从Cursor对象中获得数据。由于电子词典使用了SQLite数据库来保存英文单词信息,因此,在本例中使用从Cursor对象中获得数据的方法来创建Adapter对象。这需要我们自定义一个DictionaryAdapter类,该类需要从CursorAdapter类继承,代码如下:view plaincopy to clipboardprint?1. publicclassDictionaryAdapterextendsCursorAdapter 2. 3. privateLayoutInflaterlayoutInflater; 4. Override5. publicCharSequenceconvertToString(Cursorcursor) 6. 7. returncursor=null?:cursor.getString(cursor 8. .getColumnIndex(_id); 9. 10. /用于将_id字段(也就是english字段)的值设置TextView组件的文本 11. /view参数表示用于显示列表项的TextView组件 12. privatevoidsetView(Viewview,Cursorcursor) 13. 14. TextViewtvWordItem=(TextView)view; 15. tvWordItem.setText(cursor.getString(cursor.getColumnIndex(_id); 16. 17. 18. Override19. publicvoidbindView(Viewview,Contextcontext,Cursorcursor) 20. 21. setView(view,cursor); 22. 23. 24. Override25. publicViewnewView(Contextcontext,Cursorcursor,ViewGroupparent) 26. 27. Viewview=layoutInflater.inflate(R.layout.word_list_item,null); 28. setView(view,cursor); 29. returnview; 30. 31. publicDictionaryAdapter(Contextcontext,Cursorc,booleanautoRequery) 32. 33. super(context,c,autoRequery); 34. /通过系统服务获得LayoutInflater对象 35. 36. layoutInflater=(LayoutInflater)context 37. .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 38. 39. public class DictionaryAdapter extends CursorAdapter private LayoutInflater layoutInflater; Override public CharSequence convertToString(Cursor cursor) return cursor = null ? : cursor.getString(cursor .getColumnIndex(_id); / 用于将_id字段(也就是english字段)的值设置TextView组件的文本 / view参数表示用于显示列表项的TextView组件 private void setView(View view, Cursor cursor) TextView tvWordItem = (TextView) view; tvWordItem.setText(cursor.getString(cursor.getColumnIndex(_id); Override public void bindView(View view, Context context, Cursor cursor) setView(view, cursor); Override public View newView(Context context, Cursor cursor, ViewGroup parent) View view = layoutInflater.inflate(R.layout.word_list_item, null); setView(view, cursor); return view; public DictionaryAdapter(Context context, Cursor c, boolean autoRequery) super(context, c, autoRequery); / 通过系统服务获得LayoutInflater对象 layoutInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 在编写DictionaryAdapter类时应注意如下4点: 1. 为了将Cursor对象与AutoCompleteTextView组件绑定, DictionaryAdapter类必须从CursorAdapter类继承。 2. 由于CursorAdapter类中的convertToString方法直接返回了Cursor对象的地址,因此,在DictionaryAdapter类中必须覆盖convertToString方法,以返回当前选中的单词。CursorAdapter类中的convertToString方法的源代码。view plaincopy to clipboardprint?1. publicCharSequenceconvertToString(Cursorcursor) 2. 3. /如果cursor不为null,返回Cursor对象的地址(cursor.toString() 4. returncursor=null?:cursor.toString(); 5. public CharSequence convertToString(Cursor cursor) / 如果cursor不为null,返回Cursor对象的地址(cursor.toString() return cursor = null ? : cursor.toString(); 覆盖后的convertToToString方法的源代码如下:view plaincopy to clipboardprint?1. publicCharSequenceconvertToString(Cursorcursor) 2. 3. returncursor=null?:cursor.getString(cursor 4. .getColumnIndex(_id); 5. public CharSequence convertToString(Cursor cursor) return
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论