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

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

       本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020

      通过之前的10节,已实现了记事本的大部分功能,有添加拍照,添加照片,添加录音,添加绘图,添加手写,另外细心的可以发现,底部菜单还有一个更多的选项,这个以后再实现,用于扩展记事本的功能。

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

先看效果图:

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

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

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

数据库操作

DatabaseOperation.java

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast;

public class DatabaseOperation {
	private SQLiteDatabase db;
	private Context context;
	public DatabaseOperation(Context context,SQLiteDatabase db) {
		this.db = db;
		this.context = context;
	}
	 //数据库的打开或创建
    public void create_db(){
    	//创建或打开数据库
    	db = SQLiteDatabase.openOrCreateDatabase(context.getFilesDir().toString()+"/mynotes.db3", null);
    	db.execSQL("DROP TABLE IF EXISTS studentScore");  

    	if(db == null){
    		Toast.makeText(context,"数据库创建不成功",Toast.LENGTH_LONG).show();
    	}
    	//Toast.makeText(context,"数据库创建成功",Toast.LENGTH_LONG).show();
    	
    	//创建表
    	db.execSQL("create table if not exists notes(_id integer primary key autoincrement," +
    			"title text," +
    			"context text," +
    			"time varchar(20))");
    	
    }
    public void insert_db(String title,String text,String time){
    	
    	
    	if(text.isEmpty()){
    		Toast.makeText(context, "各字段不能为空", Toast.LENGTH_LONG).show();
    	}
    	else{
    		db.execSQL("insert into notes(title,context,time) values('"+ title+"','"+ text+ "','"+time+"');");
        	//Toast.makeText(context, "插入成功", Toast.LENGTH_LONG).show();
    	}
    	
    }
    public void update_db(String title,String text,String time,int item_ID){
    	if( text.isEmpty()){
    		Toast.makeText(context, "各字段不能为空", Toast.LENGTH_LONG).show();
    	}
    	else{
    		//String sql = "update main set class1='" + class1 + "',class2='" + class2 + "',class3='" + class4 + "',class4='" + class4 + "'where days='" + days + "';";
    		db.execSQL("update notes set context='"+text+ "',set title='"+title+"',set time='"+time+"'where _id='" + item_ID+"'");
        	//Toast.makeText(context, "修改成功", Toast.LENGTH_LONG).show();
        	}
    }
    
    public Cursor query_db(){
    	Cursor cursor = db.rawQuery("select * from notes",null);
    	return cursor;
    }
    public Cursor query_db(int item_ID){
    	Cursor cursor = db.rawQuery("select * from notes where _id='"+item_ID+"';",null);
    	return cursor;
    	
    }
    public void delete_db(int item_ID){
    	db.execSQL("delete from notes where _id='" + item_ID+"'");
    	//Toast.makeText(context, "删除成功", Toast.LENGTH_LONG).show();
    }
    //关闭数据库
    public void close_db(){
    	db.close();
    }
}
        有了这些数据库的相关操作,下面就开始实现保存记事,修改记事,删除记事,查询记事的功能。

保存记事

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

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

主要代码为:  

        //取得EditText中的内容
	String context = et_Notes.getText().toString();
	if(context.isEmpty()){
		Toast.makeText(AddActivity.this, "记事为空!", Toast.LENGTH_LONG).show();
	}
	else{
		//取得当前时间
		SimpleDateFormat   formatter   =   new   SimpleDateFormat   ("yyyy-MM-dd HH:mm");  
		Date   curDate   =   new   Date(System.currentTimeMillis());//获取当前时间 
		String   time   =   formatter.format(curDate);
		//截取EditText中的前一部分作为标题,用于显示在主页列表中
		String title = getTitle(context);
		//打开数据库
		dop.create_db();
		//判断是更新还是新增记事
		if(editModel.equals("newAdd")){
			//将记事插入到数据库中	
				dop.insert_db(title,context,time);
		}
		//如果是编辑则更新记事即可
		else if(editModel.equals("update")){
			dop.update_db(time,context,time,item_Id);
		}
		dop.close_db();
		//结束当前activity
		AddActivity.this.finish();
	}
         其中, getTitle()函数就是为了截取记事正文的前15字作为该记事的标题;editModel表示当前是新增记事还是修改记事。getTitle()如下:

       //截取EditText中的前一部分作为标题,用于显示在主页列表中
	private String getTitle(String context){
	    //定义正则表达式,用于匹配路径
	    Pattern p=Pattern.compile("/([^\\.]*)\\.\\w{3}");
	    Matcher m=p.matcher(context);
	    StringBuffer strBuff = new StringBuffer();
	    String title = "";
	    int startIndex = 0;
	    while(m.find()){
	    	//取出路径前的文字
	    	if(m.start() > 0){
	    		strBuff.append(context.substring(startIndex, m.start()));
	    	}
	    	//取出路径
	    	String path = m.group().toString();
	    	//取出路径的后缀
	    	String type = path.substring(path.length() - 3, path.length());
	    	//判断附件的类型
	    	if(type.equals("amr")){
	    		strBuff.append("[录音]");
	    	}
	    	else{
	    		strBuff.append("[图片]");
	    	}
	        startIndex = m.end();
	        //只取出前15个字作为标题
	        if(strBuff.length() > 15){
	        	//统一将回车,等特殊字符换成空格
	        	title = strBuff.toString().replaceAll("\r|\n|\t", " ");
	        	return title;
	        }
	    }
	    strBuff.append(context.substring(startIndex, context.length()));
    	//统一将回车,等特殊字符换成空格
	    title = strBuff.toString().replaceAll("\r|\n|\t", " ");
        return title;
	}
        这里主要是用到了正则表达式,用于匹配是普通文字还是图片录音等,如果是图片录音,则在标题中显然图片录音文字即可,这里还用到了一个技巧,就是return 的上一句,目的就是为了将标题中的回车等特殊字符统一换成空格。

浏览(修改)记事  

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

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

private SQLiteDatabase db;
private DatabaseOperation dop;
private ListView lv_notes;
......
//数据库操作
dop = new DatabaseOperation(this, db);
lv_notes = (ListView)findViewById(R.id.lv_notes);
//显示记事列表 
showNotesList();
//为记事列表添加监听器
lv_notes.setOnItemClickListener(new ItemClickEvent());

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

    //显示记事列表
    private void showNotesList(){
    	//创建或打开数据库
        dop.create_db();
        Cursor cursor = dop.query_db();
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, 
        		R.layout.note_item,
        		cursor, 
        		new String[]{"_id","title","time"}, new int[]{R.id.tv_note_id,R.id.tv_note_title,R.id.tv_note_time});
        lv_notes.setAdapter(adapter);
        dop.close_db();
    	
    }

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

    //记事列表单击监听器
    class ItemClickEvent implements OnItemClickListener{

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			tv_note_id = (TextView)view.findViewById(R.id.tv_note_id);
			int item_id = Integer.parseInt(tv_note_id.getText().toString());
			Intent intent = new Intent(MainActivity.this,AddActivity.class);
			intent.putExtra("editModel", "update");
			intent.putExtra("noteId", item_id);
			startActivity(intent);
		}
    }
       这样,当单击一个列表项时,就会新打开一个activity,用于显示记事的详细内容,这里依然用的是新增记事Activity,这样做的好处就是在查看记事的同时,也可以修改,这也是大多数记事软件所采用的方法,而且,也能过intent将一些信息传递给AddActivity,其中editModel是编辑模式,因为这里是查看或者修改,所以当再次点击保存时,就更新原有的记事即可,并不是又新增加一条记事;noteId是为了让AddActivity知道该读取数据库的中那一条数据。相应的,要在AddActivity里添加代码取出数据并显示,主要代码如下:

        //加载数据
	private void loadData(){
		
		//如果是新增记事模式,则将editText清空
		if(editModel.equals("newAdd")){
			et_Notes.setText("");
		}
		//如果编辑的是已存在的记事,则将数据库的保存的数据取出,并显示在EditText中
		else if(editModel.equals("update")){
			tv_title.setText("编辑记事");
			
			dop.create_db();
			Cursor cursor = dop.query_db(item_Id);
			cursor.moveToFirst();
			//取出数据库中相应的字段内容
			String context = cursor.getString(cursor.getColumnIndex("context"));
			
			//定义正则表达式,用于匹配路径
		    Pattern p=Pattern.compile("/([^\\.]*)\\.\\w{3}"); 
		    Matcher m=p.matcher(context);
		    int startIndex = 0;
		    while(m.find()){
		    	//取出路径前的文字
		    	if(m.start() > 0){
		    		et_Notes.append(context.substring(startIndex, m.start()));
		    	}
		    	
		        SpannableString ss = new SpannableString(m.group().toString());
		        
		        //取出路径
		    	String path = m.group().toString();
		    	//取出路径的后缀
		    	String type = path.substring(path.length() - 3, path.length());
		    	Bitmap bm = null;
		    	Bitmap rbm = null;
		    	//判断附件的类型,如果是录音文件,则从资源文件中加载图片
		    	if(type.equals("amr")){
		    		bm = BitmapFactory.decodeResource(getResources(), R.drawable.record_icon);
		    		//缩放图片
			        rbm = resize(bm,200);

		    	}
		    	else{
		    		//取出图片
			        bm = BitmapFactory.decodeFile(m.group());
			        //缩放图片
			        rbm = resize(bm,480);
		    	}
		    	
		        //为图片添加边框效果
		        rbm = getBitmapHuaSeBianKuang(rbm);
		        System.out.println(rbm.getWidth()+"-------"+rbm.getHeight());
		        ImageSpan span = new ImageSpan(this, rbm);
		        ss.setSpan(span,0, m.end() - m.start(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		        et_Notes.append(ss);
		        startIndex = m.end();
		    }
		    //将最后一个图片之后的文字添加在TextView中 
		    et_Notes.append(context.substring(startIndex,context.length()));
			dop.close_db();
		}	
	}
    
      这里同样是用到了正则表达式,因为要识别路径。通过这个方法,在每次打开AddActivity时调用该方法,即能适用于新增记事,也可以用于修改记事。

删除记事

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

......

//为记事列表添加长按事件
lv_notes.setOnItemLongClickListener(new ItemLongClickEvent());
......

    //记事列表长按监听器
    class ItemLongClickEvent implements OnItemLongClickListener{

		@Override
		public boolean onItemLongClick(AdapterView<?> parent, View view,
				int position, long id) {
			tv_note_id = (TextView)view.findViewById(R.id.tv_note_id);
			int item_id = Integer.parseInt(tv_note_id.getText().toString());
			simpleList(item_id);
			return true;
		}
    	
    } 
    //简单列表对话框,用于选择操作
    public void simpleList(final int item_id){
		AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this,R.style.custom_dialog);
		alertDialogBuilder.setTitle("选择操作");
		alertDialogBuilder.setIcon(R.drawable.ic_launcher);
		alertDialogBuilder.setItems(R.array.itemOperation, new android.content.DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				
				switch(which){
					//编辑
					case 0 :
						Intent intent = new Intent(MainActivity.this,AddActivity.class);
						intent.putExtra("editModel", "update");
						intent.putExtra("noteId", item_id);
						startActivity(intent);
						break;
					//删除
					case 1 :
						dop.create_db();
						dop.delete_db(item_id);
						dop.close_db();
						//刷新列表显示
						lv_notes.invalidate();
						showNotesList();
						break;
				}
			}
		});
		alertDialogBuilder.create();
		alertDialogBuilder.show();
	}
    
     
       以上,就实现了记事的保存,修改,删除的功能,到此,记事本的功能已基本完成,剩下的就是后续的完善与优化,以及新增功能了。

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