首页 > 代码库 > android项目 之 记事本(11) ----- 添加数据库

android项目 之 记事本(11) ----- 添加数据库

这节就来为我们的记事本添加数据库支持,这样,就可以在添加记事后将其保存在数据库中,方便下次浏览,修改,删除等。

先看效果图:

     三张图片分别演示了保存记事,查看记事,删除记事。

     对于数据库而言,无非就是涉及到数据库的创建,增删改查。

     为了将数据库的操作封装起来,单独写了一个类,如下:

数据库操作

DatabaseOperation.java

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. import android.content.Context;  
  2. import android.database.Cursor;  
  3. import android.database.sqlite.SQLiteDatabase;  
  4. import android.widget.Toast;  
  5.   
  6. public class DatabaseOperation {  
  7.     private SQLiteDatabase db;  
  8.     private Context context;  
  9.     public DatabaseOperation(Context context,SQLiteDatabase db) {  
  10.         this.db = db;  
  11.         this.context = context;  
  12.     }  
  13.      //数据库的打开或创建  
  14.     public void create_db(){  
  15.         //创建或打开数据库  
  16.         db = SQLiteDatabase.openOrCreateDatabase(context.getFilesDir().toString()+"/mynotes.db3", null);  
  17.         db.execSQL("DROP TABLE IF EXISTS studentScore");    
  18.   
  19.         if(db == null){  
  20.             Toast.makeText(context,"数据库创建不成功",Toast.LENGTH_LONG).show();  
  21.         }  
  22.         //Toast.makeText(context,"数据库创建成功",Toast.LENGTH_LONG).show();  
  23.           
  24.         //创建表  
  25.         db.execSQL("create table if not exists notes(_id integer primary key autoincrement," +  
  26.                 "title text," +  
  27.                 "context text," +  
  28.                 "time varchar(20))");  
  29.           
  30.     }  
  31.     public void insert_db(String title,String text,String time){  
  32.           
  33.           
  34.         if(text.isEmpty()){  
  35.             Toast.makeText(context, "各字段不能为空", Toast.LENGTH_LONG).show();  
  36.         }  
  37.         else{  
  38.             db.execSQL("insert into notes(title,context,time) values(‘"+ title+"‘,‘"+ text+ "‘,‘"+time+"‘);");  
  39.             //Toast.makeText(context, "插入成功", Toast.LENGTH_LONG).show();  
  40.         }  
  41.           
  42.     }  
  43.     public void update_db(String title,String text,String time,int item_ID){  
  44.         if( text.isEmpty()){  
  45.             Toast.makeText(context, "各字段不能为空", Toast.LENGTH_LONG).show();  
  46.         }  
  47.         else{  
  48.             //String sql = "update main set class1=‘" + class1 + "‘,class2=‘" + class2 + "‘,class3=‘" + class4 + "‘,class4=‘" + class4 + "‘where days=‘" + days + "‘;";  
  49.             db.execSQL("update notes set context=‘"+text+ "‘,title=‘"+title+"‘,time=‘"+time+"‘where _id=‘" + item_ID+"‘");  
  50.             //Toast.makeText(context, "修改成功", Toast.LENGTH_LONG).show();  
  51.             }  
  52.     }  
  53.       
  54.     public Cursor query_db(){  
  55.         Cursor cursor = db.rawQuery("select * from notes",null);  
  56.         return cursor;  
  57.     }  
  58.     public Cursor query_db(int item_ID){  
  59.         Cursor cursor = db.rawQuery("select * from notes where _id=‘"+item_ID+"‘;",null);  
  60.         return cursor;  
  61.           
  62.     }  
  63.     public void delete_db(int item_ID){  
  64.         db.execSQL("delete from notes where _id=‘" + item_ID+"‘");  
  65.         //Toast.makeText(context, "删除成功", Toast.LENGTH_LONG).show();  
  66.     }  
  67.     //关闭数据库  
  68.     public void close_db(){  
  69.         db.close();  
  70.     }  
  71. }  

        有了这些数据库的相关操作,下面就开始实现保存记事,修改记事,删除记事,查询记事的功能。

保存记事

         当编辑好一个记事时,这时点击顶部的保存按钮,就将所写的记事插入到数据库中,当然了,如果记事里面有图片,录音等,并没有图片,录音本身存储到数据库,而是将其所在路径存储在数据库中,等到再次查看时,再从数据库中读取,并根据所保存的路径取出源文件。

         保存记事的思想就是取出EditText中的内容,并从中截取前一部分作为该记事的标题,以及同时也保存了添加记事的时间。

主要代码为:  

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1.        //取得EditText中的内容  
  2. String context = et_Notes.getText().toString();  
  3. if(context.isEmpty()){  
  4.     Toast.makeText(AddActivity.this, "记事为空!", Toast.LENGTH_LONG).show();  
  5. }  
  6. else{  
  7.     //取得当前时间  
  8.     SimpleDateFormat   formatter   =   new   SimpleDateFormat   ("yyyy-MM-dd HH:mm");    
  9.     Date   curDate   =   new   Date(System.currentTimeMillis());//获取当前时间   
  10.     String   time   =   formatter.format(curDate);  
  11.     //截取EditText中的前一部分作为标题,用于显示在主页列表中  
  12.     String title = getTitle(context);  
  13.     //打开数据库  
  14.     dop.create_db();  
  15.     //判断是更新还是新增记事  
  16.     if(editModel.equals("newAdd")){  
  17.         //将记事插入到数据库中      
  18.             dop.insert_db(title,context,time);  
  19.     }  
  20.     //如果是编辑则更新记事即可  
  21.     else if(editModel.equals("update")){  
  22.         dop.update_db(title,context,time,item_Id);  
  23.     }  
  24.     dop.close_db();  
  25.     //结束当前activity  
  26.     AddActivity.this.finish();  
  27. }  

         其中, getTitle()函数就是为了截取记事正文的前15字作为该记事的标题;editModel表示当前是新增记事还是修改记事。getTitle()如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1.        //截取EditText中的前一部分作为标题,用于显示在主页列表中  
  2.     private String getTitle(String context){  
  3.         //定义正则表达式,用于匹配路径  
  4.         Pattern p=Pattern.compile("/([^\\.]*)\\.\\w{3}");  
  5.         Matcher m=p.matcher(context);  
  6.         StringBuffer strBuff = new StringBuffer();  
  7.         String title = "";  
  8.         int startIndex = 0;  
  9.         while(m.find()){  
  10.             //取出路径前的文字  
  11.             if(m.start() > 0){  
  12.                 strBuff.append(context.substring(startIndex, m.start()));  
  13.             }  
  14.             //取出路径  
  15.             String path = m.group().toString();  
  16.             //取出路径的后缀  
  17.             String type = path.substring(path.length() - 3, path.length());  
  18.             //判断附件的类型  
  19.             if(type.equals("amr")){  
  20.                 strBuff.append("[录音]");  
  21.             }  
  22.             else{  
  23.                 strBuff.append("[图片]");  
  24.             }  
  25.             startIndex = m.end();  
  26.             //只取出前15个字作为标题  
  27.             if(strBuff.length() > 15){  
  28.                 //统一将回车,等特殊字符换成空格  
  29.                 title = strBuff.toString().replaceAll("\r|\n|\t", " ");  
  30.                 return title;  
  31.             }  
  32.         }  
  33.         strBuff.append(context.substring(startIndex, context.length()));  
  34.         //统一将回车,等特殊字符换成空格  
  35.         title = strBuff.toString().replaceAll("\r|\n|\t", " ");  
  36.         return title;  
  37.     }  

        这里主要是用到了正则表达式,用于匹配是普通文字还是图片录音等,如果是图片录音,则在标题中显然图片录音文字即可,这里还用到了一个技巧,就是return 的上一句,目的就是为了将标题中的回车等特殊字符统一换成空格。

浏览(修改)记事  

        在保存了记事后,当然就要从数据库取出,并以原来的格式显示给用户。设想一下,在新增了记事后,返回主页或者重新进入主页,就应该看到当前已保存的记事列表,所以在主页的Activity中应该放置一个列表(ListView)用于显示从数据库中取出的数据。当点击列表的项目时,就应该打开查看该记事的详细内容了。

        因为在保存记事时已经截取了一部分作为标题,所以在主页记事列表上只显示标题,时间,而不显然详细内容。主要代码下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. private SQLiteDatabase db;  
  2. private DatabaseOperation dop;  
  3. private ListView lv_notes;  
  4. ......  
  5. //数据库操作  
  6. dop = new DatabaseOperation(this, db);  
  7. lv_notes = (ListView)findViewById(R.id.lv_notes);  
  8. //显示记事列表   
  9. showNotesList();  
  10. //为记事列表添加监听器  
  11. lv_notes.setOnItemClickListener(new ItemClickEvent());  

        其中,showNotesList()就是用来显然记事列表的,如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //显示记事列表  
  2. private void showNotesList(){  
  3.     //创建或打开数据库  
  4.     dop.create_db();  
  5.     Cursor cursor = dop.query_db();  
  6.     SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,   
  7.             R.layout.note_item,  
  8.             cursor,   
  9.             new String[]{"_id","title","time"}, new int[]{R.id.tv_note_id,R.id.tv_note_title,R.id.tv_note_time});  
  10.     lv_notes.setAdapter(adapter);  
  11.     dop.close_db();  
  12.       
  13. }  

       上面只实现了浏览记事列表的功能,那么点击列表项目,自然就是查看或修改记事的详细内容了,所以为列表添加单击事件,并在其监听器中实现从数据库读取相应的记事内容,并显示,如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1.    //记事列表单击监听器  
  2.    class ItemClickEvent implements OnItemClickListener{  
  3.   
  4.     @Override  
  5.     public void onItemClick(AdapterView<?> parent, View view, int position,  
  6.             long id) {  
  7.         tv_note_id = (TextView)view.findViewById(R.id.tv_note_id);  
  8.         int item_id = Integer.parseInt(tv_note_id.getText().toString());  
  9.         Intent intent = new Intent(MainActivity.this,AddActivity.class);  
  10.         intent.putExtra("editModel", "update");  
  11.         intent.putExtra("noteId", item_id);  
  12.         startActivity(intent);  
  13.     }  
  14.    }  

       这样,当单击一个列表项时,就会新打开一个activity,用于显示记事的详细内容,这里依然用的是新增记事Activity,这样做的好处就是在查看记事的同时,也可以修改,这也是大多数记事软件所采用的方法,而且,也能过intent将一些信息传递给AddActivity,其中editModel是编辑模式,因为这里是查看或者修改,所以当再次点击保存时,就更新原有的记事即可,并不是又新增加一条记事;noteId是为了让AddActivity知道该读取数据库的中那一条数据。相应的,要在AddActivity里添加代码取出数据并显示,主要代码如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1.         //加载数据  
  2.     private void loadData(){  
  3.           
  4.         //如果是新增记事模式,则将editText清空  
  5.         if(editModel.equals("newAdd")){  
  6.             et_Notes.setText("");  
  7.         }  
  8.         //如果编辑的是已存在的记事,则将数据库的保存的数据取出,并显示在EditText中  
  9.         else if(editModel.equals("update")){  
  10.             tv_title.setText("编辑记事");  
  11.               
  12.             dop.create_db();  
  13.             Cursor cursor = dop.query_db(item_Id);  
  14.             cursor.moveToFirst();  
  15.             //取出数据库中相应的字段内容  
  16.             String context = cursor.getString(cursor.getColumnIndex("context"));  
  17.               
  18.             //定义正则表达式,用于匹配路径  
  19.             Pattern p=Pattern.compile("/([^\\.]*)\\.\\w{3}");   
  20.             Matcher m=p.matcher(context);  
  21.             int startIndex = 0;  
  22.             while(m.find()){  
  23.                 //取出路径前的文字  
  24.                 if(m.start() > 0){  
  25.                     et_Notes.append(context.substring(startIndex, m.start()));  
  26.                 }  
  27.                   
  28.                 SpannableString ss = new SpannableString(m.group().toString());  
  29.                   
  30.                 //取出路径  
  31.                 String path = m.group().toString();  
  32.                 //取出路径的后缀  
  33.                 String type = path.substring(path.length() - 3, path.length());  
  34.                 Bitmap bm = null;  
  35.                 Bitmap rbm = null;  
  36.                 //判断附件的类型,如果是录音文件,则从资源文件中加载图片  
  37.                 if(type.equals("amr")){  
  38.                     bm = BitmapFactory.decodeResource(getResources(), R.drawable.record_icon);  
  39.                     //缩放图片  
  40.                     rbm = resize(bm,200);  
  41.   
  42.                 }  
  43.                 else{  
  44.                     //取出图片  
  45.                     bm = BitmapFactory.decodeFile(m.group());  
  46.                     //缩放图片  
  47.                     rbm = resize(bm,480);  
  48.                 }  
  49.                   
  50.                 //为图片添加边框效果  
  51.                 rbm = getBitmapHuaSeBianKuang(rbm);  
  52.                 System.out.println(rbm.getWidth()+"-------"+rbm.getHeight());  
  53.                 ImageSpan span = new ImageSpan(this, rbm);  
  54.                 ss.setSpan(span,0, m.end() - m.start(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  55.                 et_Notes.append(ss);  
  56.                 startIndex = m.end();  
  57.             }  
  58.             //将最后一个图片之后的文字添加在TextView中   
  59.             et_Notes.append(context.substring(startIndex,context.length()));  
  60.             dop.close_db();  
  61.         }     
  62.     }  
  63.       

      这里同样是用到了正则表达式,因为要识别路径。通过这个方法,在每次打开AddActivity时调用该方法,即能适用于新增记事,也可以用于修改记事。

删除记事

       删除记事的实现还是在主页Activity中实现,当长按列表项目时,弹出操作选择,共有两个,一个是编辑,一个是删除,这里的编辑是和单击列表项的查看记事的功能一样,主要是删除,当选中了删除时,就将相应的记事条目从数据库中删除,并刷新列表。主要代码如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
    1. ......  
    2.   
    3. //为记事列表添加长按事件  
    4. lv_notes.setOnItemLongClickListener(new ItemLongClickEvent());  
    5. ......  
    6.   
    7.     //记事列表长按监听器  
    8.     class ItemLongClickEvent implements OnItemLongClickListener{  
    9.   
    10.         @Override  
    11.         public boolean onItemLongClick(AdapterView<?> parent, View view,  
    12.                 int position, long id) {  
    13.             tv_note_id = (TextView)view.findViewById(R.id.tv_note_id);  
    14.             int item_id = Integer.parseInt(tv_note_id.getText().toString());  
    15.             simpleList(item_id);  
    16.             return true;  
    17.         }  
    18.           
    19.     }   
    20.     //简单列表对话框,用于选择操作  
    21.     public void simpleList(final int item_id){  
    22.         AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this,R.style.custom_dialog);  
    23.         alertDialogBuilder.setTitle("选择操作");  
    24.         alertDialogBuilder.setIcon(R.drawable.ic_launcher);  
    25.         alertDialogBuilder.setItems(R.array.itemOperation, new android.content.DialogInterface.OnClickListener() {  
    26.               
    27.             @Override  
    28.             public void onClick(DialogInterface dialog, int which) {  
    29.                   
    30.                 switch(which){  
    31.                     //编辑  
    32.                     case 0 :  
    33.                         Intent intent = new Intent(MainActivity.this,AddActivity.class);  
    34.                         intent.putExtra("editModel", "update");  
    35.                         intent.putExtra("noteId", item_id);  
    36.                         startActivity(intent);  
    37.                         break;  
    38.                     //删除  
    39.                     case 1 :  
    40.                         dop.create_db();  
    41.                         dop.delete_db(item_id);  
    42.                         dop.close_db();  
    43.                         //刷新列表显示  
    44.                         lv_notes.invalidate();  
    45.                         showNotesList();  
    46.                         break;  
    47.                 }  
    48.             }  
    49.         });  
    50.         alertDialogBuilder.create();  
    51.         alertDialogBuilder.show();  
    52.      

android项目 之 记事本(11) ----- 添加数据库