使用SharedPreferences
File存储
SQLite数据库
使用SharedPreferences
1.1 SharedPreferences与Editor简介
应用程序有少量的数据需要保存,而且这些数据的格式很简单,都是普通的字符串、标量类型的值等,比如应用程序的各种配置信息,对于这种数据,Android提供了SharedPreferences。
SharedPreferences保存的数据主要是类似于配置信息格式的数据,因此它保存的数据主要是简单类型的key-value对。 SharedPreferences接口主要负责读取应用程序的Preferences数据,它提供了如下常方法来访问SharedPreferences中的key-value对。
boolean contains(String key):判断SharedPreferences是否包含特定key的数据。
abstract Map<String, ?>getAll():获取SharedPreferences数据里全部的key-value对。
boolean getXxx(String key,xxx defValue):获取SharedPreferences数据里指定的key对应的value。如果key值不存在,返回默认值defValue。其中xxx可以是boolean、float、int、long、String等各种基本类型的值。
SharedPreferences接口本身并没有提供写入数据的能力,而是通过SharedPreferences的内部接口, SharedPreferences调用edit()方法即可获取它所对应的Editor对象,提供了如下方法向SharedPreferences写入数据。
SharedPreferences.Editor clear():清空SharedPreferences里所有数据。
SharedPreferences.Editor putXxx(String key, xxx value):向SharedPreferences存入指定key对应的数据。其中xxx可以是boolean、float、int、long、String等各种基本类型的值。
SharedPreferences.Editor remove(String key):删除SharedPreferences里指定的key对应的数据项。
boolean commit() :当Editor编辑完成后,调用该方法提交修改。
SharedPreferences是一个接口,程序无法直接创建其实例,只能通过Context提供的getSharedPreferences(String name,int mode) 方法来获取SharedPreferences实例。该方法的第二个参数支持如下几个值。
Context.MODE_PRIVATE:指定SharedPreferences数据只能被本应用程序读、写。
Context.MODE_WORLD_READABLE:指定SharedPreferences数据能被其他应用程读,但不能写。
Context.MODE_WORLD_WRITEABLE:指定SharedPreferences数据能被其他应用程读、写。
例:SharedPreferences的存储位置和格式:
SharedPreferencesDemo.java
public class SharedPreferencesDemo extends Activity
{
	SharedPreferences preferences;
	SharedPreferences.Editor editor;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获取只能被本应用程序读、写的SharedPreferences对象
		preferences = getSharedPreferences("hello", MODE_WORLD_READABLE);
		editor = preferences.edit();
		Button read = (Button) findViewById(R.id.read);
		Button write = (Button) findViewById(R.id.write);
		read.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				//读取字符串数据
				String time = preferences.getString("time", null);
				//读取int类型的数据
				int randNum = preferences.getInt("random", 0);
				String result = time == null ? "您暂时还未写入数据"
					: "写入时间为:" + time 
					+ "\n上次生成的随机数为:" + randNum;
				//使用Toast提示信息
				Toast.makeText(SharedPreferencesTest.this , 
					result , 5000)
					.show();
			}
		});
		write.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 "
					+ "hh:mm:ss");
				// 存入当前时间
				editor.putString("time", sdf.format(new Date()));
				// 存入一个随机数
				editor.putInt("random", (int) (Math.random() * 100));
				// 提交所有存入的数据
				editor.commit();
			}
		});
	}
}
 
运行程序后,点击“写入数据”,程序将完成SharedPreferences写入写入完成后,打开DDMS的File Explorer面板,SharedPreferences数据保存在/data/datta/com.whq/shared_prefs目录下, SharedPreferences数据是以XML格式保存。
1.2 要读、写其他应用的SharedPreferences
要读、写其他应用的SharedPreferences,前提是创建该SharedPreferences的应用程序指定相应的访问权限,例如指定了MODE_WORLD_READABLE,这表明该SharedPreferences可被其他应用程序读取;指定MODE_WORLD_WRITEABLE,这表明该SharedPreferences可被其他程序写入。
为了读取其他程序的SharedPreferences,可按如下步骤进行。
需要创建其他程序对应的Context。
调用其他应用程序的Context的getSharedPreferences(String name,int mode) 即可获取相应的SharedPreferences对象。
如果需要向其他应用的SharedPreferences数据写入数据,调用SharedPreferences的edit()方法获取相应的Editor即可。
例:读取其他应用程序的SharedPreferences数据:
UseCount .java
package com.Xxx;
public class UseCount extends Activity
{
	SharedPreferences preferences;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		preferences = getSharedPreferences("count", MODE_WORLD_READABLE);
		//读取SharedPreferences里的count数据
		int count = preferences.getInt("count" , 0);
		//显示程序以前使用的次数
		Toast.makeText(this , 
			"程序以前被使用了" + count + "次。", 10000)
			.show();
		Editor editor = preferences.edit();
		//存入数据
		editor.putInt("count" , ++count);
		//提交修改
		editor.commit();	
	}
}
ReadOtherPreferences.java
public class ReadOtherPreferences extends Activity
{
	Context useCount;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		//Context useCount = null;
		try
		{
		   // 获取其他程序所对应的Context(com.Xxx:UseCount所在包名)
			useCount = createPackageContext("com.Xxx",
				Context.CONTEXT_IGNORE_SECURITY);
		}
		catch (NameNotFoundException e)
		{
			e.printStackTrace();
		}
		// 使用其他程序的Context获取对应的SharedPreferences
		SharedPreferences prefs = useCount.getSharedPreferences("count",
			Context.MODE_WORLD_READABLE);
		// 读取数据
		int count = prefs.getInt("count", 0);
		TextView show = (TextView) findViewById(R.id.show);
		// 显示读取的数据内容
		show.setText("UseCount应用程序以前被使用了" + count + "次。");
	}
}
 
File存储
2.1 openFileOutput和openFileInput
Context提供了如下两个方法来打开本应用程序的数据文件夹里的文件IO流。
FileInputStream openFileInput(String name):打开应用程序的数据文件夹下的name文件对应的输入流。
FileOutputStream openFileOutput(String name,int mode):打开应用程序的数据文件夹下的name文件对应输出流。
上面两个方法分别用于打开文件输入流、输出流。其中第二个方法的第二个参数指定打开文件夹的模式,该模式支持如下值。
MODE_PRIVATE:该文件只能被当前程序读写。
MODE_APPEND:以追加方式打开该文件,应用程序可以向该文件追加内容。
MODE_WORLD_READABLE:该文件的内容可以被其他程序读取。
MODE_WORLD_WRITEABLE:该文件的内容可由其他程序读写。
Context还提供了如下几个方法来访问应用程序的数据文件夹。
getDir(String name,int mode):在应用程序的数据文件夹下获取或创建name对应的子目录。
File getFilesDir():获取该应用程序的数据文件夹的绝对路径。
String[] fileList():返回该应用程序的数据文件夹下的全部文件。
deleteFile(String):删除该应用程序的数据文件夹下的指定内容。
例:读写应用程序数据文件夹下内容:
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <EditText
        android:id="@+id/edit1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:lines="4" />
    <Button
        android:id="@+id/write"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/write" />
    <EditText
        android:id="@+id/edit2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cursorVisible="false"
        android:editable="false"
        android:lines="4" />
    <Button
        android:id="@+id/read"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/read" />
</LinearLayout>
FileTest.java
public class FileTest extends Activity
{
	final String FILE_NAME = "test.txt";
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		System.out.println(new StringBuilder("a").append("b").append("c")
			.toString());
		// 获取两个按钮
		Button read = (Button) findViewById(R.id.read);
		Button write = (Button) findViewById(R.id.write);
		// 获取两个文本框
		final EditText edit1 = (EditText) findViewById(R.id.edit1);
		final EditText edit2 = (EditText) findViewById(R.id.edit2);
		// 为write按钮绑定事件监听器
		write.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 将edit1中的内容写入文件中
				write(edit1.getText().toString());
				edit1.setText("");
			}
		});
		read.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				// 读取指定文件中的内容,并显示出来
				edit2.setText(read());
			}
		});
	}
	private String read()
	{
		try
		{
			// 打开文件输入流
			FileInputStream fis = openFileInput(FILE_NAME);
			byte[] buff = new byte[1024];
			int hasRead = 0;
			StringBuilder sb = new StringBuilder("");
			while ((hasRead = fis.read(buff)) > 0)
			{
				sb.append(new String(buff, 0, hasRead));
			}
			return sb.toString();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
	private void write(String content)
	{
		try
		{
			// 以追加模式打开文件输出流
			FileOutputStream fos = openFileOutput(FILE_NAME, MODE_APPEND);
			// 将FileOutputStream包装成PrintStream
			PrintStream ps = new PrintStream(fos);
			// 输出文件内容
			ps.println(content);
			ps.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}
 
注:test.txt所在位置:打开File Explorer:data/data/com.Xxx包名/file/test.txt
2.2 读写SD卡上的文件
当程序通过Context的openFileInput或openFileOutput来打开文件输入流、输出流时,程序所打开的都是应用程序的数据文件夹里的文件,这样所存储的文件大小可能比较有限。为了更好的存、取应用程序的大文件数据,应用程序需要读、写SD卡上的文件。步骤如下:
调用Environment的getExternalStorageState()方法判断手机上是否插入了SD卡,并且应用程序具有读写SD卡的权限。
调用Environment的getExternalStorageDirectory()方法来获取SD卡的目录。
使用FileInputStream、FileOutputStream、FileReader或FileWriter读写SD卡里的文件。
例:读写SD卡的内容:
SDCardTest.java
public class SDCardTest extends Activity
{
	final String FILE_NAME = "/test.txt";
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获取两个按钮
		Button read = (Button) findViewById(R.id.read);
		Button write = (Button) findViewById(R.id.write);
		// 获取两个文本框
		final EditText edit1 = (EditText) findViewById(R.id.edit1);
		final EditText edit2 = (EditText) findViewById(R.id.edit2);
		// 为write按钮绑定事件监听器
		write.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 将edit1中的内容写入文件中
				write(edit1.getText().toString());
				edit1.setText("");
			}
		});
		read.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				// 读取指定文件中的内容,并显示出来
				edit2.setText(read());
			}
		});
	}
	private String read()
	{
		try
		{
			//如果手机插入了SD卡,而且应用程序具有访问SD的权限
			if (Environment.getExternalStorageState()
				.equals(Environment.MEDIA_MOUNTED))
			{
				//获取SD卡对应的存储目录
				File sdCardDir = Environment.getExternalStorageDirectory();
				//获取指定文件对应的输入流
				FileInputStream fis = new FileInputStream(sdCardDir
					.getCanonicalPath()	+ FILE_NAME);
				//将指定输入流包装成BufferedReader
				BufferedReader br = new BufferedReader(new 
					InputStreamReader(fis));
				StringBuilder sb = new StringBuilder("");
				String line = null;
				while((line = br.readLine()) != null)
				{
					sb.append(line);
				}
				return sb.toString();
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
	private void write(String content)
	{
		try
		{	
			//如果手机插入了SD卡,而且应用程序具有访问SD的权限
			if (Environment.getExternalStorageState()
				.equals(Environment.MEDIA_MOUNTED))
			{
				//获取SD卡的目录
				File sdCardDir = Environment.getExternalStorageDirectory();
				File targetFile = new File(sdCardDir.getCanonicalPath()
					+ FILE_NAME);
				//以指定文件创建	RandomAccessFile对象
				RandomAccessFile raf = new RandomAccessFile(
					targetFile , "rw");
				//将文件记录指针移动到最后
				raf.seek(targetFile.length());
				// 输出文件内容
				raf.write(content.getBytes());
				raf.close();
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}
 
应用程序读、写SD卡文件请注意:
Android模拟器可通过mksdcard命令来创建虚拟存储卡
为了读写SD卡上的数据,必须在应用程序的AndroidManifest.xml中添加读写SD卡的权限。配置内容如下:
<!--SD卡创建与删除文件权限-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- SD卡写入数据权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
SQLite数据库
Android系统集成了一个轻量级的数据库:SQLite,SQLite只是一个嵌入式的数据库引擎,专门适用于资源有限的设备上(如手机、PDA等)适量数据存取。 SQLite数据库只是一个文件,不需要安装、启动服务器进程。
3.1 简介SQLiteDatabase
Android提供了SQLiteDatabase代表一个数据库(底层就是一个数据库文件),一旦应用程序获得了代表指定数据库的SQLiteDatabase对象,接下来就可以管理、操作数据库了。
SQLiteDatabase提供了如下静态方法来打开一个文件对应的数据库
SQLiteDatabase openDatabase(String path, SQLiteDatabase. CursorFactory factroy, int flags):打开path文件所代表SQLite数据库。
SQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory):打开或创建(如果 不存在)path文件所代表SQLite数据库。
在程序中获取SQLiteDatabase对象后,接下来就可调用其如下方法来操作数据库。
execSQL(String sql,Object[] bindArgs):执行带占位符的SQL语句。
execSQL(String sql):执行SQL语句。
insert(String table,String nullColumnHack,ContentValues values):向执行表中插入数据。
update(String table,ContentValues values,String whereClause,String[] whereArgs):更新指定数据库。
delete(String table,String whereClause,String[] whereArgs):删除指定表中的特定数据。
Cursor query(String table,String[] columns,String selection, String[] selectionArgs,String groupBy,String having,String orderBy):对执行数据表执行查询。
Cursor query(String table,String[] columns,String selection, String[] selectionArgs,String groupBy,String having,String orderBy,String limit):对执行数据表执行查询,limit对数控制最多查询几条记录。
rawQuery(String sql,String[] selectionArgs):执行带占位符的SQL查询。
begin Transaction():开始事务。
end Transaction():结束事务。
上面查询方法都是返回一个Cursor对象,Android中的Cursor类似于JDBC的ResultSet,Cursor提供如下方法来移动查询结果的记录指针。
move(int offset):将记录指针向上或向下移动指定的行数.
boolean moveToFirst():将记录指针移到到第一行。
boolean moveToLast():将记录指针移到到最后一行。
boolean moveToNext():将记录指针移到到下一行。
boolean moveToPosition(int position):将记录指针移到到指定行。
boolean moveToPrevious():将记录指针移到到上一行。
一旦记录指针移到到指定行后,接下来就可以调用Cursor的getXxx()方法来获取该行的指定列的数据。
3.2 创建数据库和表
使用SQLiteDatabase的静态方法即可打开或创建数据库,例如如下代码:
SQLiteDatabase.openOrCreateDatabase(“/mt/db/temp.db3”,null);
上面的代码即可返回一个SQLiteDatabase对象,该对象的execSQL可执行任意的SQL语句,因此程序可通过如下代码在程序中创建数据表:
//定义建表语句
sql=“create table user_inf(user_id integer primary key,”+” user_name varchar(255),”+”user_pass varchar(255))”
//执行SQL语句
db.execSQL(sql);
在程序中执行上面的代码即可在数据库中创建一个数据表。
3.3使用SQL语句操作SQLite数据库
使用SQLiteDatabase进行数据库操作的步骤如下:
获取SQLiteDatabase对象,进行与数据库连接。
调用SQLiteDatabase的方法来执行SQL语句。
操作SQL语句的执行结果,比如用SimpleCursorAdapter封装成Cursor。
调用close()方法,关闭SQLiteDatabase数据库,回收资源。
例:
DBTest.java
public class DBTest extends Activity
{
	SQLiteDatabase db;
	Button bn = null;
	ListView listView;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);		
		//创建或打开数据库(此处需要使用绝对路径)
		db = SQLiteDatabase.openOrCreateDatabase(this.getFilesDir()
			.toString() + "/test.db3" , null);		
		listView = (ListView)findViewById(R.id.show);
		bn = (Button)findViewById(R.id.ok);
		bn.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
		//获取用户输入
		String title = ((EditText)findViewById(R.id.title))
			.getText().toString();
		String content = ((EditText)findViewById(R.id.content))
			.getText().toString();
		try 
		{
			insertData(db , title , content);
			Cursor cursor = db.rawQuery("select * from news_inf", null);
			inflateList(cursor);
		}
		catch(SQLiteException  se)
		{
			//执行DDL创建数据表
		db.execSQL("create table news_inf(_id integer primary key autoincrement,"
			+ " news_title varchar(50),"
			+ " news_content varchar(255))");
		//执行insert语句插入数据
		insertData(db , title , content);
		//执行查询
		Cursor cursor = db.rawQuery("select * from news_inf", null);
		inflateList(cursor);
		}
	}			
		});		
	}
	private void insertData(SQLiteDatabase db
		, String title , String content)
	{
		//执行插入语句
		db.execSQL("insert into news_inf values(null , ? , ?)"
			, new String[]{title , content});
	}
	private void inflateList(Cursor cursor)
	{
		//填充SimpleCursorAdapter
		SimpleCursorAdapter adapter = new SimpleCursorAdapter(
			DBTest.this , R.layout.line, cursor 
			, new String[]{"news_title" , "news_content"}
			, new int[]{R.id.my_title , R.id.my_content});
		//显示数据
		listView.setAdapter(adapter);
	}
	@Override
	public void onDestroy()
	{
		super.onDestroy();
		//退出程序时关闭SQLiteDatabase
		if (db != null && db.isOpen())
		{
			db.close();
		}
	}
}
 
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <EditText
        android:id="@+id/title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:lines="2" />
    <Button
        android:id="@+id/ok"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/insert" />
    <ListView
        android:id="@+id/show"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>
3.4使用sqlite3工具
在Android SDK的tools目录下提供了一个sqlite.exe,它是一个简单的SQLite数据库管理工具,利用该工具可以来查询、管理数据库。
SQLilte内部只支持NULL、INTEGER、REAL、TEXT和BLOB这5种数据类型。
它允许把各种类型的数据保存到任务类型的字段中,不必关心声明该字段所使用的数据类型。
SQLilte允许存入数据时忽略底层数据列实际的数据类型。
3.5 使用特定方法操作数据库
1.使用insert方法插入记录。
SQLiteDatabase的insert方法long insert(String table,String nullCoumnHack,ContentValues values)
table:代表要插入数据的表名
nullCoumnHack:代表强行插入null值的数据列的列名。
values:代表一行记录的数据。
insert方法插入的一条记录使用ContentValues存放,ContentValues类似于Map,提供了put(String key,Xxx value)方法存入数据。getAsXxx(String key)方法取出数据。
2.使用update方法更新记录
SQLiteDatabase的update方法为update(String table,ContentValues values,String whereClause,String[] whereArgs),该方法返回受此update语句影响的记录的条数。
table:代表要更新数据的表名
values:代表想更新的数据。
whereClause:满足该whereClause子句的记录将会被更新。
whereArgs:用于为whereClause子句传入参数。
3.使用delete方法删除记录
SQLiteDatabase的delete方法为delete(String table,String whereClause,String[] whereArgs),该方法返回受此delete语句影响的记录的条数。
table:代表要删除数据的表名
whereClause:满足该whereClause子句的记录将会被删除。
whereArgs:用于为whereClause子句传入参数。
4.使用query方法查询记录
SQLiteDatabase的query方法的签名为Cusor query(boolean distinct,String table,String[] columns,String selection, String[] selectionArgs,String groupBy,String having,String orderBy,String limit):参数说明如下。
distinct:指定是否去除重复记录。
table:代表查询数据的表名。
columns:要查询出来的列名。
selection:查询条件子句。
selectionArgs:占位符传入参数值。
groupBy:用于控制分组。
having:用于对分组进行过滤。
orderBy:用于对记录进行排序。
limit:用于进行分页。
3.6 SQLiteOpenHelper
SQLiteOpenHelper是一个辅助类,可用于管理数据库的创建和版本更新。SQLiteOpenHelper是个抽象类,一般的用法是创建SQLiteOpenHelper的子类,并重写它的onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)方法。
SQLiteOpenHelper包含如下常用方法:
getReadableDatabase():以读写的方法打开数据库对应SQLiteDatabase对象。
getWritableDatabase():以写的方法打开数据库对应SQLiteDatabase对象。
onCreate():当第一次创建数据库时回调该方法。
onUpgrade():当数据库版本更新时回调该方法。
close():关闭所打开的SQLiteDatabase对象
例子:简单生词本
MyDatabaseHelper.java
public class MyDatabaseHelper extends SQLiteOpenHelper
{
	final String CREATE_TABLE_SQL =
		"create table dict(_id integer primary key autoincrement , word , detail)";
	public MyDatabaseHelper(Context context, String name, int version)
	{
		super(context, name, null, version);
	}
	@Override
	public void onCreate(SQLiteDatabase db)
	{
		// 第一个使用数据库时自动建表
		db.execSQL(CREATE_TABLE_SQL);
	}
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
	{
		System.out.println("--------onUpdate Called--------" 
			+ oldVersion + "--->" + newVersion);
	}
}
 
Dict.java
public class Dict extends Activity
{
	MyDatabaseHelper dbHelper;
	Button insert = null;
	Button search = null;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);		
		// 创建MyDatabaseHelper对象,指定数据库版本为1,此处使用相对路径即可,
		// 数据库文件自动会保存在程序的数据文件夹的databases目录下。
		dbHelper = new MyDatabaseHelper(this 
			, "myDict.db3" , 1);
		insert = (Button)findViewById(R.id.insert);
		search = (Button)findViewById(R.id.search);	
		insert.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				//获取用户输入
				String word = ((EditText)findViewById(R.id.word))
					.getText().toString();
				String detail = ((EditText)findViewById(R.id.detail))
					.getText().toString();
				//插入生词记录
				insertData(dbHelper.getReadableDatabase() , word , detail);
				//显示提示信息
				Toast.makeText(Dict.this, "添加生词成功!" , 8000)
					.show();
			}			
		});	
		search.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 获取用户输入
				String key = ((EditText) findViewById(R.id.key)).getText()
					.toString();
				// 执行查询
				Cursor cursor = dbHelper.getReadableDatabase().rawQuery(
					"select * from dict where word like ? or detail like ?", 
					new String[]{"%" + key + "%" , "%" + key + "%"});				
		//创建一个Bundle对象
		Bundle data = new Bundle();
		data.putSerializable("data", converCursorToList(cursor));
		//创建一个Intent
		Intent intent = new Intent(Dict.this
			, ResultActivity.class);
		intent.putExtras(data);
		//启动Activity
		startActivity(intent);
			}
		});
	}
	protected ArrayList<Map<String , String>>
		converCursorToList(Cursor cursor)
	{
		ArrayList<Map<String , String>> result = 
			new ArrayList<Map<String , String>>();
		//遍历Cursor结果集
		while(cursor.moveToNext())
		{
			//将结果集中的数据存入ArrayList中
			Map<String , String> map = new 
				HashMap<String , String>();
			//取出查询记录中第2列、第3列的值
			map.put("word" , cursor.getString(1));
			map.put("detail" , cursor.getString(2));
			result.add(map);
		}
		return result;		
	}
	private void insertData(SQLiteDatabase db
		, String word , String detail)
	{
		//执行插入语句
		db.execSQL("insert into dict values(null , ? , ?)"
			, new String[]{word , detail});
	}
	@Override
	public void onDestroy()
	{
		super.onDestroy();
		//退出程序时关闭MyDatabaseHelper里的SQLiteDatabase
		if (dbHelper != null)
		{
			dbHelper.close();
		}}}
ResultActivity.java
public class ResultActivity extends Activity
{
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.popup);
		ListView listView = (ListView)findViewById(R.id.show);
		Intent intent = getIntent();
		//获取该intent所携带的数据
		Bundle data = intent.getExtras();
		//从Bundle数据包中取出数据
		@SuppressWarnings("unchecked")
		List<Map<String , String>> list = 
			(List<Map<String , String>>)data.getSerializable("data");
		//将List封装成SimpleAdapter
		SimpleAdapter adapter = new SimpleAdapter(
			ResultActivity.this , list
			, R.layout.line , new String[]{"word" , "detail"}
			, new int[]{R.id.word , R.id.detail});
		//填充ListView
		listView.setAdapter(adapter);
	}
}
 
Main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <EditText android:id="@+id/word" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/input" /> <EditText android:id="@+id/detail" android:layout_width="fill_parent" android:layout_height="wrap_content" android:lines="3" android:hint="@string/input" /> <Button android:id="@+id/insert" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/insert" /> <EditText android:id="@+id/key" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/record" /> <Button android:id="@+id/search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/search" /> <ListView android:id="@+id/show" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
string.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">生词本</string> <string name="insert">添加生词</string> <string name="search">查找</string> <string name="detail">解释</string> <string name="input">请输入...</string> <string name="record">暂无</string> </resources>
 
Android笔记----Android的数据存储和IO操作
原文:http://blog.csdn.net/boby2012/article/details/42421639