db.execSQL(sql);
4、实现增加、更新和删除这 3 种操作有两种方法:
不管是哪种方法,记得先 getWritableDatabase()
(a)用 execSQL 方法直接执行相应的 SQL 语句,比如增加(如下)。
SQLiteDatabase db = getWritableDatabase();
String insert_sql="INSERT INTO <表名>(<列 1>,<列 2>,…)values(<值 1>,<值 2>,…)";
db.execSQL(insert_sql);
(b)使用相应的 insert、update 和 delete 方法
I.insert 方法需要使用 ContentValues 来存放要添加的数据,见下图
II.update 方法需要使用 ContentValues 和 Where 语句。(下图只是说明性代码)
III、delete 方法需要使用 where 语句。(下图只是说明性代码)
5、查询数据
实现查询操作可以使用 rawQuery 或 query 函数,它们的区别类似于上面,前者直接执行
SQL 语句,后者是通过参数组合产生 SQL 语句。(下图只是说明性代码)
进行查询前,记得先 getReadableDatabase()
rawQuery 或者 query 函数返回的都是 Cursor,关于 Cursor 类的详细介绍请看下面
的链接:
http://www.cnblogs.com/TerryBlog/archive/2010/07/05/1771459.html
三. SQLiteOpenHelper
该类是SQLiteDatabase一个辅助类。这个类主要生成一 个数据库,并对数据库的版本进行管理。当在程序当中调用这个类的方法getWritableDatabase()或者 getReadableDatabase()方法的时候,如果当时没有数据,那么Android系统就会自动生成一个数据库。 SQLiteOpenHelper 是一个抽象类,我们通常需要继承它,并且实现里面的3个函数:
1.onCreate(SQLiteDatabase)
在数据库第一次生成的时候会调用这个方法,也就是说,只有在创建数据库的时候才会调用,当然也有一些其它的情况,一般我们在这个方法里边生成数据库表。
2. onUpgrade(SQLiteDatabase,int,int)
当数据库需要升级的时候,Android系统会主动的调用这个方法。一般我们在这个方法里边删除数据表,并建立新的数据表,当然是否还需要做其他的操作,完全取决于应用的需求。
3. onOpen(SQLiteDatabase):
这是当打开数据库时的回调函数,一般在程序中不是很常使用。
Content Provider 使用
1.适用场景
1) ContentProvider为存储和读取数据提供了统一的接口
2) 使用ContentProvider,应用程序可以实现数据共享
3) android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)
2.ContentProvider简介
当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。
3.使用 getContentResolver 方法读取联系人列表
Cursor cursor =getContentResolver().query(ContactsContract.Contacts. CONTENT_URI , null, null, null, null);
判断某条联系人的信息中,是否有电话号码。
int isHas =Integer. parseInt (cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts. HAS_PHONE_NUMBER )));
取出该条联系人信息中的电话号码
Cursor c =getContentResolver().query(ContactsContract.CommonDataKinds.Phone. CON
TENT_URI , null, ContactsContract.CommonDataKinds.Phone. CONTACT_ID + "
= " + id, null, null);
while (c.moveToNext()) {
number +=c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone. N N
UMBER )) + " ";
c.close();
自定义的对话框实现
使用 LayoutInflater 类,如下:
如此之后,我们就可以将一个 layout 的内容(dialoglayout)全都显示在对话框
(builder)里了。之后便可以对 layout 里面的元素进行操作了。
实现一个生日备忘簿
技术要求:
1、 使用 SQLite 数据库保存生日的相关信息,使得每次运行程序都可以显示出已经存 储在数据库里的内容;
2、 使用 ContentProvider 来获取对应寿星的电话号码;
功能要求:
1、 主界面包含增加生日条目按钮和生日信息列表;(见图 1,图 2)
2、 点击<增加条目>按钮跳转到次界面;
3、 次界面输入生日相关信息后点击<增加>按钮会返回主界面(同时更新主界面的生日 信息列表),且姓名字段不能为空,姓名字段不能重复 (见图 3,图 4)
4、 主界面中的列表点击事项处理:
a) 单击(查看并可修改该生日条目):(见图 5)
i. 弹出对话框,显示该条目的相关信息,并提供修改。
ii. 同时,显示该生日条目寿星的电话号码;
iii. 点击<保存修改>按钮,更新主界面的生日信息列表
b) 长按(可删除该生日条目):(见图 6)
i. 弹出对话框,显示是否删除;
ii. 点击<是>按钮,删除该生日条目,并更新主界面的生日信息列表
图 1 首次启动 图 2 增加一些条目后
图 3 名字不能重复 图 4 长按处理
图 5 点击处理 图 6 名字不能为空
本次实验主要是实现一个联系人生日备忘录,实现数据存储的功能。本次实验主要涉及 SQLite 数据库的使用以及在获取通讯录中联系人电话信息时的 ContentProvider 的使用。
首先,写好几个界面的 XML 布局文件。这里我们需要使用初始界面、增粘条 目界面、自定义对话框界面以及 listview 的 item 界面共四个 xml 布局文件。需 要注意的是,为了保证列表标题栏和列表项能够对齐,这里将标题栏布局和 listview 的 item 界面布局中的三个 TextView 的 layout_weight 属性比例设置 为 1:1:2。
接下来完成 MainActivity.java 类,在初始化控件后,主要完成几个点击按 钮的事件。单击增加条目按钮,我们将跳转到AddActivity.java 的界面中:
并设置了一个退出按钮:
在增加了 listview 的条目之后,单击 listview 我们将获取手机中的通讯录 中的联系人电话信息,并跳转到自定义对话框中进行编辑。
获取手机中的通讯录中的联系人电话信息需要使用 Content Provider。首先我们在 AndroidManifest.xml 文件里声明读取通讯录的权限(这里具体的方 法在“实验中遇到的问题及解决方法”一栏中详述,这里就不加赘述)。然后使 用 getContentResolver 方法读取联系人列表,并判断某条联系人的信息中,是 否有电话号码,若存在相应的联系人号码,则取出该条联系人信息中的电话号码; 如果手机通讯录中没有对应的联系人则将手机设为无:
自定义的对话框实现需要使用 LayoutInflater 类:
之后,我们就可以将一个 layout 的内容(dialoglayout)全都显示在对话框(builder)里,然后便可以对 layout 里面的元素进行操作。
在自定义对话框中,我们需要按照要求进行设置:
除了这些以外,我们还需要实时更新 UI,这里,我们定义一个状态更新的 函数,在需要调用的时候进行调用进行实时更新(同时也进行数据库内容的更新):
在 AddActivity 类中,我们主要还是完成各个按钮的事件。 在增加条目的按钮事件中,我们需要根据需要输出相应的 Toast 信息(当编辑框为空时,输出相应的 Toast 信息;当姓名编辑框与数据库中已存在的数据相 同时,输出相应的 Toast 信息):
还有清除和取消按钮,这里就不加赘述。
在我们这次实验的 主要内容数据库中 ( MyDataBase 类中 ) , 使 用 SQLiteOpenHelper 的子类能更方便实现要求。首先我们需要创建类:
创建数据库,可直接执行创建数据库的 SQl 语句:
在对应的位置使用相应的 insert、update 和 delete 方法,完成实现增加、更新和删除这3种操作 。 这里, 我们先getWritableDatabase(),用 execSQL方法直接执行相应的SQL语句(实现查 询操作使用 rawQuery):
SQLite 简介:
SQLite 是一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很 少的内存就有很好的性能。此外它还是开源的,任何人都可以使用它。
(1)Android 开发中使用 SQLite 数据库
Activities 可以通过 Content Provider 或者 Service 访问一个数据库。 创建数据库
Android 不自动提供数据库。在 Android 应用程序中使用 SQLite,必须自 己创建数据库,然后创建表、索引,填充数据。Android 提供了 SQLiteOpenHelper 帮助你创建一个数据库,你只要继承 SQLiteOpenHelper 类,就可以轻松的创建
数据库。SQLiteOpenHelper 类根据开发应用程序的需要,封装了创建和更新数 据库使用的逻辑。SQLiteOpenHelper 的子类,至少需要实现三个方法:
a.构造函数
调用父类 SQLiteOpenHelper 的构造函数。这个方法需要四个参数:上下文 环境(例如,一个 Activity),数据库名字,一个可选的游标工厂(通常是 Null), 一个代表你正在使用的数据库模型版本的整数。
b.onCreate()方法
它需要一个 SQLiteDatabase 对象作为参数,根据需要对这个对象填充表和 初始化数据。
c.onUpgrage() 方法
它需要三个参数,一个 SQLiteDatabase 对象,一个旧的版本号和一个新的 版本号,这样你就可以清楚如何把一个数据库从旧的模型转变到新的模型。
(2)调用 getReadableDatabase() 或 getWriteableDatabase() 方法,你可以 得到 SQLiteDatabase 实例,具体调用那个方法,取决于你是否需要改变数据库 的内容:
db=(new DatabaseHelper(getContext())).getWritableDatabase();
return (db == null) ? false : true;
上面这段代码会返回一个 SQLiteDatabase 类的实例,使用这个对象,你就 可以查询或者修改数据库。
当完成了对数据库的操作(例如 Activity 已经关闭),需要调用 SQLiteDatabase 的 Close() 方法来释放掉数据库连接。
(3)创建表和索引
为了创建表和索引,需要调用 SQLiteDatabase 的 execSQL() 方法来执行 DDL 语句。如果没有异常,这个方法没有返回值。
SQLite 会自动为主键列创建索引。 通常情况下,第一次创建数据库时创建了表和索引。如果你不需要改变表的
schema,不需要删除表和索引 . 删除表和索引,需要使用 execSQL() 方法调用 DROP INDEX 和 DROP TABLE 语句。
(4)给表添加数据
有两种方法可以给表添加数据。
像上面创建表一样,你可以使用 execSQL() 方法执行 INSERT, UPDATE, DELETE 等语句来更新表的数据。execSQL() 方法适用于所有不返回结果的 SQL 语 句 。 另 一 种 方 法 是 使 用 SQLiteDatabase 对 象 的 insert(), update(), delete() 方法。
ContentProvider 简介:
当应用继承 ContentProvider 类,并重写该类用于提供数据和存储数据的方 法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但 数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需 要进行文件操作读写数据;采用 sharedpreferences 共享数据, 需要使用 sharedpreferences API 读写数据。而使用 ContentProvider 共享数据的好处是 统一了数据访问方式。
1)ContentProvider 为存储和读取数据提供了统一的接口
2)使用 ContentProvider,应用程序可以实现数据共享
3)android 内置的许多数据都是使用 ContentProvider 形式,供开发者调用 的(如视频,音频,图片,通讯录等)
创建ContentProvider
要创建我们自己的Content Provider的话,我们需要遵循以下几步:
a. 创建一个继承了ContentProvider父类的类
b. 定义一个名为CONTENT_URI,并且是public static final的Uri类型的类变量,你必须为其指定一个唯一的字符串值,最好的方案是以类的全名称, 如:
public static final Uri CONTENT_URI = Uri.parse( “content://com.google.android.MyContentProvider”);
c. 定义你要返回给客户端的数据列名。如果你正在使用Android数据库,必须为其定义一个叫_id的列,它用来表示每条记录的唯一性。
d. 创建你的数据存储系统。大多数Content Provider使用Android文件系统或SQLite数据库来保持数据,但是你也可以以任何你想要的方式来存储。
e. 如果你要存储字节型数据,比如位图文件等,数据列其实是一个表示实际保存文件的URI字符串,通过它来读取对应的文件数据。处理这种数据类型的Content Provider需要实现一个名为_data的字段,_data字段列出了该文件在Android文件系统上的精确路径。这个字段不仅是供客户端使用,而且也可以供ContentResolver使用。客户端可以调用ContentResolver.openOutputStream()方法来处理该URI指向的文件资源;如果是ContentResolver本身的话,由于其持有的权限比客户端要高,所以它能直接访问该数据文件。
f. 声明public static String型的变量,用于指定要从游标处返回的数据列。
g. 查询返回一个Cursor类型的对象。所有执行写操作的方法如insert(), update() 以及delete()都将被监听。我们可以通过使用ContentResover().notifyChange()方法来通知监听器关于数据更新的信息。
h. 在AndroidMenifest.xml中使用<provider>标签来设置Content Provider。
源码下载点击这里~
1、本实验实验环境:
操作系统 Windows 10
实验软件 Android Studio 2.2.1
虚拟设备:Nexus_5X
API:23
2、贴代码的时候由于插入代码框的大小问题,代码格式不太严整,望见谅~