Android笔记----Android的数据存储和IO操作

使用SharedPreferences

File存储

SQLite数据库

 

 

 

 

 

使用SharedPreferences

1.1 SharedPreferencesEditor简介

        应用程序有少量的数据需要保存,而且这些数据的格式很简单,都是普通的字符串、标量类型的值等,比如应用程序的各种配置信息,对于这种数据,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可以是booleanfloatintlongString等各种基本类型的值。

 

SharedPreferences接口本身并没有提供写入数据的能力,而是通过SharedPreferences的内部接口, SharedPreferences调用edit()方法即可获取它所对应的Editor对象,提供了如下方法向SharedPreferences写入数据。

       SharedPreferences.Editor clear():清空SharedPreferences里所有数据。

       SharedPreferences.Editor putXxx(String key, xxx value):向SharedPreferences存入指定key对应的数据。其中xxx可以是booleanfloatintlongString等各种基本类型的值。

       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写入写入完成后,打开DDMSFile 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

       调用其他应用程序的ContextgetSharedPreferences(String name,int mode) 即可获取相应的SharedPreferences对象。

       如果需要向其他应用的SharedPreferences数据写入数据,调用SharedPreferencesedit()方法获取相应的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 openFileOutputopenFileInput

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 Explorerdata/data/com.Xxx包名/file/test.txt

 

 

 

2.2 读写SD卡上的文件

当程序通过ContextopenFileInputopenFileOutput来打开文件输入流、输出流时,程序所打开的都是应用程序的数据文件夹里的文件,这样所存储的文件大小可能比较有限。为了更好的存、取应用程序的大文件数据,应用程序需要读、写SD卡上的文件。步骤如下:

       调用EnvironmentgetExternalStorageState()方法判断手机上是否插入了SD卡,并且应用程序具有读写SD卡的权限。

       调用EnvironmentgetExternalStorageDirectory()方法来获取SD卡的目录。

       使用FileInputStreamFileOutputStreamFileReaderFileWriter读写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系统集成了一个轻量级的数据库:SQLiteSQLite只是一个嵌入式的数据库引擎,专门适用于资源有限的设备上(如手机、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 orderByString limit):对执行数据表执行查询,limit对数控制最多查询几条记录。

rawQuery(String sql,String[] selectionArgs):执行带占位符的SQL查询。

begin Transaction():开始事务。

end Transaction():结束事务。

上面查询方法都是返回一个Cursor对象,Android中的Cursor类似于JDBCResultSetCursor提供如下方法来移动查询结果的记录指针。

       move(int offset):将记录指针向上或向下移动指定的行数.

       boolean moveToFirst():将记录指针移到到第一行。

       boolean moveToLast():将记录指针移到到最后一行。

       boolean moveToNext():将记录指针移到到下一行。

       boolean moveToPosition(int position):将记录指针移到到指定行。

       boolean moveToPrevious():将记录指针移到到上一行。

一旦记录指针移到到指定行后,接下来就可以调用CursorgetXxx()方法来获取该行的指定列的数据。

 

 

 

 

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 SDKtools目录下提供了一个sqlite.exe,它是一个简单的SQLite数据库管理工具,利用该工具可以来查询、管理数据库。

SQLilte内部只支持NULLINTEGERREALTEXTBLOB5种数据类型。

它允许把各种类型的数据保存到任务类型的字段中,不必关心声明该字段所使用的数据类型。

SQLilte允许存入数据时忽略底层数据列实际的数据类型。

 

3.5 使用特定方法操作数据库

1.使用insert方法插入记录。

       SQLiteDatabaseinsert方法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方法更新记录

       SQLiteDatabaseupdate方法为update(String table,ContentValues values,String whereClause,String[] whereArgs),该方法返回受此update语句影响的记录的条数。

       table:代表要更新数据的表名

       values:代表想更新的数据。

       whereClause:满足该whereClause子句的记录将会被更新。

       whereArgs:用于为whereClause子句传入参数。

 

3.使用delete方法删除记录

       SQLiteDatabasedelete方法为delete(String table,String whereClause,String[] whereArgs),该方法返回受此delete语句影响的记录的条数。

       table:代表要删除数据的表名

       whereClause:满足该whereClause子句的记录将会被删除。

       whereArgs:用于为whereClause子句传入参数。

 

4.使用query方法查询记录

       SQLiteDatabasequery方法的签名为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>


 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值