2015.07.24
我是一个比较懒的人,于是乎在如何将单词表导入SQLite上面就显得很烦.....老是想一个办法又觉得不可行,想一个办法又感觉不符合要求.....于是经过再三考虑,在兼顾可行性和功能实现上我最终选择通过这样一个比较无脑的办法来实现这个过程----我把一个单词表的txt文件放到asset文件夹里面(因为这个文件夹里面的东西是不会北压缩的),它里面的单词的格式是这样的:
格式非常easy---就是单词+释义,而且还没有记忆遍数,因为我打算放在SQLite里面..不过!!重要的事情说三遍:格式不对!格式不对!格式不对!
格式怎么不对了那?原因是这样的:我这个txt文件肯定不是自己写的,于是乎必然是从别的文件里面考下来的(原谅我不会用Android/Java读取excel文件......阿西).我是从一个excel文件里面拷贝过来的,所以中间的空格比较多!于是便产生了接下来的问题(后面会一一说到).....废话少说,我遇到的问题就是怎么想办法把一坨空格变成一个空格.我考虑了一下直接操作比较困难,于是我找的替代方案是再写一个文件做SQLite的读入文件.见下:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class StringTest {
//@SuppressWarnings({ "null" })
public static void main(String[] args) {
try {
//用InputStreamReader的原因是因为它支持中文编码,主要是因为后面利用缓存读写文件的时候可以正常显示.
InputStreamReader fr=new InputStreamReader(new FileInputStream("vocabulary_GRE.txt"),"UTF-8");
BufferedReader br=new BufferedReader(fr);
FileWriter fw=new FileWriter("aaa.txt");//目标文件
BufferedWriter bw= new BufferedWriter(fw);
String tmpReadString;
String tmpWriteString;
while(br.ready())
{
tmpReadString=br.readLine();//按行读取
//下面声明了临时变量来进行操作
char []tmpReadArray=tmpReadString.toCharArray();
char []tmpWriteArray=new char[tmpReadArray.length];
int i=0;
int j=0;
int spacePlace = 0;
//下面的代码找出空格应该出现的位置
for(int k=0;k<tmpReadArray.length;k++)
{
if(Character.isLetter(tmpReadArray[k])&&!Character.isLetter(tmpReadArray[k+1])&&tmpReadArray[k]!='-')
{
spacePlace=k+1;
break;
}
}
//将tmpReadArray按位写到tmpWriteArray里面.其他操作是处理噪声的--文件里面有些不标准的形式或者符号需要改一下
for(i=0;i<tmpReadArray.length;i++)
{
if(i==spacePlace) tmpWriteArray[j++]=' ';
else if(tmpReadArray[i]==';') tmpWriteArray[j++]='/';
else tmpWriteArray[j++]=tmpReadArray[i];
}
tmpWriteString=String.valueOf(tmpWriteArray).trim();
//新建StringBuffer类继续处理噪声--删除不合规范的符号
StringBuffer finalWriteString=new StringBuffer(tmpWriteString.trim());
String []delete_element={"a","v","t","."," ","n"};
for(int k=0;k<5;k++)
{
while(finalWriteString.lastIndexOf(delete_element[k])>spacePlace) finalWriteString.deleteCharAt(finalWriteString.indexOf(delete_element[k]));
}
bw.write(finalWriteString.toString());
bw.newLine();
}
//释放资源
bw.flush();
bw.close();
br.close();
fw.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
上面的代码做的事情就是讲文件加了空格.在这个过程中遇到了这样一些问题----首先是编码问题,就是读出来的中文一直是乱码:最后解决方案是先将txt文件保存为UTF-8编码形式,在利用InputStreamReader这个可以指定编码的io流来读取; 其次是空格找不出来!!你敢信?我明明看到一坨空格愣是读不出来.....试了各种方法 实验了一下午最后才发现:那些空的部分并不是空格!是什么我并不知道,总之就是讲excel文件的内容拷贝到txt文件里面产生的东西....(知道真相的我真的想报警!浪费了一下午啊!!); 最后的问题在于我的txt文件是存在噪声的..就是我认为他是释义中只有中文和标点,但是实际上偶尔会有释义前面有字母(词性)的情况,这样一来我的字符串处理就变得异常艰难.我至今也不明白我明明有代码去处理这些噪声但是还是有漏网之鱼,没有办法只能自己在最终的文件里面自己进行调整....
经过非常艰苦的过程,我终于调好了要导入数据库的txt文件,下面终于可以进行导入SQLite的工作了.主要还是利用之前封装的DBManager里面的方法去返回单词集合.代码见下:
package example.mywordapp;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.util.EncodingUtils;
import android.app.Activity;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import mywordapp.wordsqlite.DBManager;
import mywordapp.wordsqlite.Word;
public class MySQLiteActivity extends Activity{
private DBManager mgr;
private ListView listView;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sqlite);
listView=(ListView)findViewById(R.id.listView);
//初始化DBManager
mgr=new DBManager(this);
}
//添加单词
public void add(View view) {
ArrayList<Word> words=new ArrayList<Word>();
String fileName = "GRE.txt"; //单词表名字 ,文件要放在asset文件夹下
String res="";
try{
//得到资源中的asset数据流
InputStream in = getResources().getAssets().open(fileName);
//利用io流或得一个res的String串,res里面的内容是整个单词表txt里面的内容
int length = in.available();
byte [] buffer = new byte[length];
in.read(buffer);
in.close();
res = EncodingUtils.getString(buffer, "UTF-8");
}catch(Exception e){
e.printStackTrace();
}
//利用String类里面的split方法将res这个大字符串分割成一个String数组,其中的一行就是一个单词
String []tmp=res.split("\n");
for(int i=0;i<tmp.length;i++)
{
//这是在利用我们之前设置好的唯一的一个空格进行二次切割,从而分离出来英语单词和中文释义,这样就可以加入到数据库了
String []tmp_word=tmp[i].split(" ");
System.out.println(i+1+" "+tmp_word[0]+" "+tmp_word[1]);
Word word=new Word(tmp_word[0],tmp_word[1],0);
words.add(word);
}
mgr.add(words);
}
//更新记忆次数---ps目前我没有更新这个方法,因为还没有进行到这里
//所以说这个方法是不能用的,因为我目前还没有解决如何传参数的问题
public void update(View view)
{
Word word=new Word();
word.en_meaning="son";
word.repeating_number=1;
mgr.updateRepeating_Number(word);
}
//利用HashMap获得单词以便查询
public void query(View view) {
List<Word> words = mgr.query();
ArrayList<Map<String, Integer>> list = new ArrayList<Map<String, Integer>>();
for (Word word : words) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("repeating_number", word.repeating_number);
//map.put("en_meaning", word.en_meaning);
list.add(map);
}
SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2,
new String[]{"en_meaning"}, new int[]{android.R.id.text1});
listView.setAdapter(adapter);
}
//删除烂熟的单词
public void delete(View view) {
Word word = new Word();
word.repeating_number = 40;
mgr.deleteAdroidWord(word);
}
//全体查询,返回的是整个单词表,然后利用SimpleAdapter和ListView绑定在一起
//注意要确保查询结果中有"_id"列
@SuppressWarnings("deprecation")
public void queryTheCursor(View view) {
Cursor c = mgr.queryTheCursor();
startManagingCursor(c); //托付给activity根据自己的生命周期去管理Cursor的生命周期
CursorWrapper cursorWrapper = new CursorWrapper(c) {
@Override
public String getString(int columnIndex) {
//在英文后加上中文
if (getColumnName(columnIndex).equals("en_meaning")) {
String cn_meaning = getString(getColumnIndex("cn_meaning"));
return super.getString(columnIndex)+" "+cn_meaning;
}
return super.getString(columnIndex);
}
};
//下面是在绑定语句----其结果是每个list显示两行:第一行是单词+释义,第二行是记忆次数.
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2,
cursorWrapper, new String[]{"en_meaning", "repeating_number"}, new int[]{android.R.id.text1, android.R.id.text2});
ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
}
}
目前只是把所有估计会用的功能写出来而已,后续还需要进行大规模改造(好怕怕.......).
上一下结果图:
我必须要说.....我的界面是抄的哪位大神的.......希望大神不要介意....原谅我不会@你........见谅~_~
接下来就是想办法解决"背单词App开发日记3里面的其他问题了",最主要的问题就是如何让屏幕上只显示一个单词----另一种表述就是如何将SQLite的数据和控件绑定到一起;其次的重点问题是如何实时更新每个当前显示的单词的记忆遍数.....加油!Franky