项目二 我爱记单词

项目情境

单词是英语学习的基础,如果能利用手机存储单词,就能随时随地地进行单词的学习。
对于英语学习者来说,这样利用碎片时间进行单词记忆能解决纸质资料携带不便的问题,也能提高学习的效率。
本项目是为了实现手机单词管理,使用者能将需要记忆的单词添加到单词库,如果单词信息存在错误可以对单词进行修改和删除。此外,使用者可以按照添加的单词库中的顺序依次查看单词,从而达到对单词的记忆目的。总体来说,该项目需要实现基于Android 系统的单词管理,包括单词的添加、删除、修改和查看,并实现用户的登录与注册,如图2-1 所示。通过该项目的任务实现,掌握用户界面设计、数据处理、数据共享、网络互联的基本方法。

图像说明文字

学习目标

  • 通过用户登录、注册界面的设计,掌握界面设计的基础,包括界面布局和常用控件、事件处理、菜单对话框等相关内容。
  • 通过用户信息存取、单词信息存取,掌握数据存取的几种方法,包括文件存取、SharedPreferences、SQLite、ContentProvider、网络存取。实现单词存取,用户信息的网络传输。

工作任务

图像说明文字

任务 2.1 用户登录界面设计

任务描述

“我爱记单词”项目需要记录学习者的相关信息,因此需要实现用户信息的管理,在该任务中实现用户登录界面的设计。其界面设计如图2-2 所示。

图像说明文字

任务目标

① 掌握界面布局和常用控件的使用。
② 掌握资源访问和背景图片设置方法。
③ 掌握事件处理的实现方法。

任务分析

该任务涉及的功能主要有界面设计、资源访问和事件处理,具体实现过程:
① 创建dict 工程;
② 设计界面布局;
③ 设置背景图片;
④ LoginActivity 中加载控件并实现按钮事件;
⑤ 配置AndroidManifest.xml 文件。

1.View 类简介
View 类主要用于显示界面,Android 应用程序中每个Activty 都对应一个显示界面,Activity 上展现的是Android 系统中的可视化组件,Android 中的任何可视化组件都是从android.view.View 继承。View 类继承于公共父类Object,View 类有很多子类。View 类的子类分为两种:直接子类,如TextView、ProgerssBar 等;间接子类,继承于ViewGroup 的布局类Layout,如GridView、ListView。其层次结构和类的简介如图2-3 所示,该类定义的概要如图2-4 所示。

图像说明文字

图像说明文字

创建View 的两种方式:使用XML 创建View 和使用Java 代码创建View。

  • 在res/layout 使用创建XML 类型的布局文件,并在Acitvity 中使用setContentView()方法将此XML 文件设置为显示视图。
  • 使用代码创建View,每一个视图组件都是一个View 类型的对象,可以在代码中使用视图类的构造方法创建View 对象,调用View 对象的setXXX 方法设置其属性。
    下面依次介绍这两种方法的实现步骤。
    ① 使用XML 文件实现界面设计,步骤如下。
    在res/layout 下创建activitymian.xml 文件,在该文件中设置布局方式为LinerLayout(线性布局),并定义一个按钮控件。

图像说明文字

在Activity 中将activitymian.xml 设置为显示界面,使用setContentView 方法。

图像说明文字

在代码中获得XML 中创建的View,实际应用中常常需要在代码中获得XML 中创建的View 对象(如TextView、Button、ProgerssBar 等),进一步对其进行操作可以使用Activity 类的findViewById( )方法获得XML 中的View 对象。

图像说明文字

②使用Java 代码创建界面,步骤如下。
下面代码创建一个TextView,并将TextView 设置为显示界面。

图像说明文字

2.布局管理器
Android 系统中提供了几种常用的布局方式:线性布局、层布局、相对布局、表格布局、坐标布局。每种布局方式都对应API 中一个类。
LinearLayout:线性布局。
FrameLayout:层叠布局。
RelativeLayout:相对布局。
TableLayout:表格布局。
AbsoluteLayout:坐标布局。
LinearLayout 为线性布局,将组件按照属性设置的水平或垂直方向按顺序排列。设置布局显示方式的属性有:方向orientation,对齐方式gravity。orientation 表示控件是水平还是垂直放置,gravity 表示是居中还是居左对齐。在Layout 中每个控件的layout_height、layout_width和android:orientation 属性是必须定义的,表示控件的高度和宽度属性设置。

图像说明文字

FrameLayout 称为层布局,将组件显示在屏幕的左上角,后面的组件覆盖前面的组件。

图像说明文字

RelativeLayout 是相对布局,相对布局指的是某个组件的位置是相对于其他组件的位置。

图像说明文字

TableLayout 是表格布局,使用TableRow 指定一行,每个组件表示一列。

图像说明文字

图像说明文字

AbsoluteLayout 是绝对布局管理器,指的是指定组件的左上角绝对坐标来指定组件的布局,通常需要设置横纵坐标layout_x 和layout_y。

图像说明文字

3.文本相关组件 显示文本的组件TextView,如邮件正文或应用程序标签等。API 中对应android. widget.TextView 类。

图像说明文字

TextView 的重要属性如下。 文本的颜色和背景:

图像说明文字

TextView 的对齐方式:

图像说明文字

字体大小:

图像说明文字

单行显示:

图像说明文字

编辑文本的组件EditText。EditText 是TextView 类的子类,具有TextView 所有属性。EditText 可以编辑文本,也可以指定输入文本的类型,通过3 种属性可以指定:android:digits、android:inputType、android:numeric。

图像说明文字

自动完成输入内容的组件AutoCompleteTextView。AutoCompleteTextView 是EditText 的子类,当用户键入文本时,能提示输入建议。
4.普通按钮
Button 类继承了TextView 类。在布局文件中,使用属性指定Button 的属性,如android:text 指定Button 显示的文本。

5.事件处理
事件处理的实现方法有3 种,分别是类本身实现事件处理接口和方法、匿名内部类实现事件处理的方法、一般内部类实现事件处理接口和方法。事件处理的实现有3 个关键步骤:实现事件处理接口implementsOnClickListener,实现事件处理的方法publicvoidonClick(Viewarg0)和设置监听方法setOnClickListener()。下面依次介绍事件处理的3 种实现方法。
① 利用类实现鼠标单击事件接口和方法。在类的定义中利用implementsOnClickListener语句实现事件单击事件接口,在类中实现接口的方法public voidonClick(View arg0),方法中利用switch 语句匹配组件产生的事件处理。在按钮事件监听方法setOnClickListener(this)实现监听。
② 匿名内部类实现鼠标单击事件处理。在按钮事件监听方法setOnClickListener()中直接利用newOnClickListener()创建事件处理对象并实现public voidonClick(View arg0)方法。
③ 一般内部类实现事件处理。创建一般内部类actLiner,该类定义中利用implementsOnClickListener 实现接口,在类中实现接口的方法public voidonClick(View arg0)。在按钮事件监听方法setOnClickListener(new actLiner() )实现监听。
事件处理方法一:利用类。

图像说明文字

事件处理方法二:利用匿名内部类。

图像说明文字

图像说明文字

事件处理方法三:利用一般内部类。

图像说明文字

图像说明文字

任务实现

1.创建dict 工程
启动ADT,在ADT 中创建工程dict,设置工程的包名、最小兼容SDK、目标SDK 等信息,创建过程如图2-5~图2-9 所示。
设置参数如下。

  • Application Name(应用名称):ABC 我爱记单词。
  • Project Name(工程名):dict。
  • Package Name(包名):com.siit.dict。
  • Minimum Required SDK(最小兼容SDK):API 7:Android2.1(Eclair)。
  • Target SDK(目标SDK):API17:Android 4.2(Jelly Bean)。
  • Compile With(编译版本):API17:Android 4.2(Jelly Bean)。
  • Theme(主题样式):Holo Light with Dark Action Bar。

图像说明文字

图像说明文字

图像说明文字

2.设计界面布局
在res\layout 文件夹中设计activity_login.xml 文件,并将控件按照图2-2 所示的方式设计。在activity_login.xml 文件中设计两个TextView 用于显示“用户名称”和“用户密码”,设计两个EidtText 用于输入“用户名称”和“用户密码”,设计两个按钮分别为“登录”和“注册新用户”。

图像说明文字

图像说明文字

3.设置背景图片
图2-10 所示为图片属性设置代码:android:background="@drawable/background"。

图像说明文字

4.LoginActivity 中加载控件并实现按钮事件
首先定义btnok、btnReg 两个按钮,并定义username、password 两个文本编辑框。在LoginActivity 的onCreate 方法中使用findViewById()方法依次加载按钮和文本控件,并使用setOnClickListener()方法实现按钮单击事件的监听,其代码如下所示。

图像说明文字

图像说明文字

5.配置AndroidManifest.xml 文件
AndroidManifest.xml 文件在创建工程时系统会自动生成。如果要更改信息,可以设置相关代码,此处修改应用程序的显示图标,将android:icon 设置为"@drawable/logo。

图像说明文字

技能训练

创建一个Android 应用程序,该程序可以输入电话号码,单击一个发送按钮,将输入的电话号码显示到当前的界面,程序效果如图2-11 所示。

图像说明文字

任务2.2 系统退出功能设计

任务描述

在任务2.1 的基础上,实现系统退出和系统介绍的功能。其执行效果如图2-12 所示。单击“About”选项后弹出对话框显示“这是一个用于单词记忆和管理的小程序!”,单击“Exit”选项后显示退出选择框。

图像说明文字

任务目标

① 掌握常见布局的使用。
② 掌握菜单的定义和创建方法。
③ 掌握对话框的定义和使用方法。

任务分析

该任务中用到的资源有字符串、图片、菜单、对话框等内容访问。实现过程中要增加菜单功能,分别实现上下文菜单和选项菜单,并在菜单选择项的单击事件弹出对话框。具体实现过程如下。
① 设置菜单选项。
② 实现“About”系统介绍的方法。
③ 实现“Exit”退出游戏的方法。
④ 在菜单事件中实现“About”与“Exit”功能。

知识要点

1.对话框 AlertDialog 类继承了Dialog 类,是其他对话框类的父类。AlertDialog 类有一个重要的内嵌类Builder。DatePickerDialog、TimePickerDialog、ProgerssDialog 是AlertDialog 类的子类,如图2-13 所示。

图像说明文字

以下是对话框上的3 种按钮。
(1)取消按钮
setNegativeButton (CharSequence text, DialogInterface.OnClickListener listener)
setNegativeButton (int textId, DialogInterface.OnClickListener listener)
(2)确认按钮
setPositiveButton (CharSequence text, DialogInterface.OnClickListener listener)
setPositiveButton (int textId, DialogInterface.OnClickListener listener)
(3)覆盖按钮
setNeutralButton (int textId, DialogInterface.OnClickListener listener)
setNeutralButton (CharSequence text, DialogInterface.OnClickListener listener)
对话框的事件处理,使用DialogInterface 可提供一系列的内嵌类,监听对话框事件。
DialogInterface.OnCancelListener
DialogInterface.OnClickListener
DialogInterface.OnDismissListener
DialogInterface.OnKeyListener
DialogInterface.OnMultiChoiceClickListener
DialogInterface.OnShowListener
ProgressDialog 类,表示进度条对话框,ProgressDialog 类结构如图2-14 所示。ProgressDialog类的主要方法有:setIcon、setTitle、setMessage、setButton。

图像说明文字

自定义对话框,使用AlertDialog 可以创建出各种对话框,如果要完全定制自己的对话框,可以自定义对话框,使用AlertDialog.Builder 类的setView 方法。
new AlertDialog.Builder(this).setView(布局文件).show()
2.菜单
Android 的菜单分为3 种类型:选项菜单(Option Menu)、上下文菜单(Context Menu)、子菜单(Sub Menu)。
① 选项菜单。当用户单击设备上的菜单按钮(Menu),触发事件弹出的菜单就是选项菜单。选项菜单最多只有6 个,超过6 个时,第六项就会自动显示为“更多选项”。
创建方法如下。

  • 覆盖Activity 的onCreateOptionsMenu(Menu menu)方法,当第一次打开菜单时调用。
  • 用Menu 的add()方法添加菜单项(MenuItem),可以调用MenuItem 的setIcon()方法为菜单项设置图标。
  • 当菜单项(MenuItem)被选中时,覆盖Acitivy 的onOptionsMenuSelected()方法响应事件。

② 上下文菜单。当用户长按Activity 页面时,弹出的菜单称为上下文菜单。
创建方法如下。

  • 覆盖Activity 的onCreateContextMenu()方法,调用Menu 的add 方法添加菜单项MenuItem。
  • 覆盖onContextItemSelected()方法,响应菜单单击事件。调用registerForContextMenu()方法,为视图注册上下文菜单。

③ 子菜单。子菜单就是将相同功能的分组进行多级显示的一种菜单,比如,Windows的“文件”菜单中就有“新建”“打开”“关闭”等子菜单。在选项菜单和上下文菜单都可以添加子菜单,但子菜单不能嵌套子菜单,这就意味着在Android 系统中,菜单只有两层。设计时需要注意的是,子菜单不支持icon。
创建方法如下。

  • 覆盖Activity 的onCreateOptionsMenu()方法,调用Menu 的addSubMenu()方法添加子菜单项。
  • 调用SubMenu 的add()方法,添加子菜单项。
  • 覆盖onCreateItemSelected()方法,响应菜单单击事件。

3.通知
Toast 是一段显示给用户的小文本,不需要用户响应,在规定时间内自动消失,API 中提供了Toast 类,创建Toast 对象。
Notification 是显示在屏幕上方状态栏的信息,Notification 需要使用NotificationManager来管理。

任务实现

1.设置菜单选项
在res\menu\activity_login.xml 文件中定义“about”和“exit”两个菜单项,内容如下。

图像说明文字

2.实现“About”系统介绍的方法
创建aboutAlert(String msg)方法,该方法是单个按钮的对话框显示。

图像说明文字

图像说明文字

3.实现“Exit”退出游戏的方法
创建exitAlert (String msg)方法,实现退出游戏对话框显示。

图像说明文字

4.在菜单事件中实现“About”与“Exit”功能
当单击about 和exit 菜单项时,调用aboutAlert(String msg)与exitAlert(String msg)方法实现“About”关于游戏与“Exit”退出游戏的功能。

图像说明文字

图像说明文字

技能训练

创建Android 应用程序,程序运行效果如图2-15 所示。
程序功能要求:
① 该应用程序具有“设置”“视频”“信息”3 个菜单;
② 单击“信息”菜单,弹出“信息”的子菜单;
③ 单击“删除”子菜单,弹出对话框,询问是否删除收件箱中所有信息。

图像说明文字

任务2.3 用户注册界面设计

任务描述

注册界面的设计,界面效果如图2-16 所示,通过TextView、EditText、RadioGroup、RadioButton、ToggleButton、CheckBox、Spinner、Button 等控件的使用实现用户注册。

图像说明文字

任务目标

① 会使用TextView 和EditText 实现用户名和密码的设置。
② 会使用RadioButton 与RadioGroup 组件实现性别设置。
③ 会使用ToggleButton 按钮实现婚姻状况显示,内容项为“OFF”和“ON”,默认项为“OFF”。
④ 会使用CheckBox 按钮实现爱好项,选择项为:阅读、游泳。
⑤ 会使用Spinner 按钮实现职务项,内容为:CEO、CFO、PM,使用数组适配器。
⑥ 会使用ListView 实现注册内容显示。

任务分析

本任务中使用TextView、EditText、RadioGroup、RadioButton、ToggleButton、CheckBox、Spinner、Button 等控件实现用户注册页面,并在结果页面显示用户注册信息。具体实现过程如下。
① 创建注册界面。
② 实现注册功能。
③ 实现登录页面向注册页面的跳转。
④ 创建结果界面。
⑤ 创建结果页面的Activity 文件。
⑥ 配置AndroidManifest.xml 文件。

知识要点

1.Activity 简介
Activity 是Android 应用程序的重要组成部分,是Android 应用程序的入口,也是用户和应用程序之间进行交互的接口。每个Android 应用程序包含很多Activity,但只显示在栈顶的Activity,每个Activity 中都可以放很多控件,可以把Activity 看作控件的容器。
创建Activity 基本步骤如下。
① 自定义创建的Activity 必须继承自Activity 类,并导入android.app.Activity 包。
② 重写onCreate( )方法,Activity 第一次运行时Android 操作系统就会自动调用onCreate方法。
③ 为Activity 添加必要的控件,定义控件,并使用findViewById()加载xml 中的控件,并根据功能需求实现相应的代码。
④ 在AndroidManifest.xml 文件中注册Activity。每个Activity 都需要在AndroidManifest.xml中注册才能使用。Android 应用程序创建时默认会将当前Activity 设置为启动Acitivity,比如本例中的LoginActivity。当建立新的Activity 时,将新建的Activity 在AndroidManifest.xml 中进行注册,如本例中的RegistActivity。

图像说明文字

2.Intent 简介
Intent 是Android 应用的各项组件之间数据通信的桥梁。当一个Activity 需要启动另一个Activity 时,需要通过Intent 表达意图:需要启动那个Intent。此外Android 应用程序通过Intent启动3 个系统组件:Activity、Service、BroadCastReceiver。 Intent 封装Android 应用程序需要启动某个组件的意图,不仅如此,Intent 还是英语程序之间通信的重要媒介,正如前面程序看到的,两个Acitivity 可以把需要交换的数据封装成Bundle 对象,然后使用Intent 来携带Bundle 对象以实现两个Activity 之间的数据传递。
表2-1 显示使用Intent 启动3 种系统组件的方法。

图像说明文字

Activity 方面。Intent 对象通过Context.starActivity(Intent intent)或Activity.starActivityFor Result(Intent intent,int requestCode())启动一个新的activity.Activity 的跳转,通过Extras 传值,当传递的数据较多时通常使用Bundle 对象实现。 Service 方面。Context.startService()方法,启动新服务或者向正在运行的服务提供新命令。Intent 对象传递到Context.bindSerivce()中将建立一个服务,建立组件间的联系。broadcastReceive 方面。Intent 对象通过Context.sendBroadcast()等发送广播,并将广播内容传递给注册了该广播的广播接收器。本任务实现过程中演示了如何使用Intent 实现Activity 之间的跳转。下面介绍Intent 对象各个属性的作用。
Intent 负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述。Android 则根据此Intent 的描述,负责找到对应的组件,将 Intent 传递给调用的组件,并完成组件的调用。Intent 对象抽象地描述了要执行的操作,其描述的基本内容可以分为Component(组件名称)、Extra(附加信息)、Action(动作)、Category(类别)、Data(数据)、Type(类型)和Flag(标志位)6 部分,其中Component 用于明确启动的目标组件,而Extra 用于“携带”需要传递的数据。
Component 指定Intent 目标组件的名称。组件名称是一个ComponentName 对象,这种对象名称是目标组件类名和目标组件所在应用程序的包名的组合。
Component 组件设置方法的简化形式:
Intent intent=new(ComponentAttr.this,SecondActivity.class);
Extras 是使用Intent 连接不同组件时在Intent 中附加额外的信息,以将数据传递给目标Activity。当传递的数据量较多时,通常以Bundle 的形式定义再存入Extras 当中,如本例中的注册页面向结果页面的跳转代码。

图像说明文字

Action 描述Intent 所触发动作名字的字符串。例如:“android.intent.action.MAIN”表示程序的主入口,不会接收数据,结束后也不返回数据。
Category 用于为Actiont 增加额外的附加类别信息。Android 在Intent 类中定义了一组静态常量便是Intent 不同的类别,如:“android.intent.category.LAUNCHER”表示目标Activity是应用程序中最优先被执行的Activity。
Category 与Action 属性的应用参见本任务程序中的AndroidMainfest.xml 文件。

图像说明文字

Data 描述Intent 要操作的数据。以URI 形式表示的数据如:content://contacts/1,可以通过setData()方法实现Data 属性的设置。
Type 用于指定该Data 所指定的Uri 对应MIME 类型。这种MIME 类型可以是任何自定义的MIME 类型,只要符合abc/xyz 格式的字符串即可。可以通过setType()方法实现Type 属性的设置。
Intent 的Flag 属性用于为该Intent 添加一些额外的控制旗标,Intent 可以调用addFlags()方法来为Intent 添加控制旗标。
3.常用按钮
Android 平台提供了很多视图组件,可以快速构建图形用户界面,常用的组件有文本组件、按钮组件、时间日期组件、列表组件、图像相关组件等。每种组件都需要相应的事件处理。事件处理的主要步骤是:实现监听器接口、覆盖监听方法、注册监听器。
ImageButton 是显示图像的按钮,是ImageView 的子类。ImageView 组件用来在屏幕上显示图片, 使用android:src 属性设置TextView 的图片源, 或者调用ImageView 类的setImageResource(int resId)方法可以为ImageView 设置显示的图片,本书任务1.2 中详细介绍了ImageView 中显示图片的方法。

ImageSwitcher 可以用于以动画方式切换图像。ImageSwitcher 使用时需要一个工厂类创建在ImageSwitcher 上显示的View 对象,如ImageView 对象。工厂类实现ViewFactory 接口,覆盖makeView 方法。

图像说明文字

常用按钮Button:如果按钮既需要显示图像又要显示文字,则使用< Button />设置。

图像说明文字

选项按钮RadioButton:RadioButton 可以构建一组单选按钮,一组互斥的单选按钮必须在一个RadioGroup 中。

图像说明文字

开关状态按钮ToggleButton:ToggleButton 与Button 的功能基本相同,ToggleButton 多了一个表示“开/关”状态的指示条。

图像说明文字

复选框按钮 CheckBox:CheckBox 多用于多选应用。

图像说明文字

4.ListView
ListView 用于以垂直列表方式显示数据项。
ListView 使用步骤:
① 声明ListView 布局文件,声明列表项的布局文件;
② 创建类继承Activity 或ListActivity;
③ 覆盖onCreate()方法;
④ 创建ListAdapter 对象,将Adapter 对象设置到ListView 中进行显示。

图像说明文字

ListView 的事件处理, 与ListView 列表项有关的事件有两种, 可以使用OnItemClickListener、OnItemSelectedListener 两个接口监听。如果Activity 类继承了ListActivity,则直接覆盖onListItemClick 即可。

图像说明文字

显示下拉列表Spinner:Spinner 的功能和ListView 组件类似,Spinner 的数据也是通过Adapter 装载,使用数组或者List 对象。

图像说明文字

5.其他控件
输入日期/时间的组件DatePicker/TimePicker。DatePicker 组件可以输入日期,范围是1900-1-1 至2100-12-31:TimePicker 组件可以输入时间,只能输入小时和分钟,默认情况是12 小时制,对应的监听器分别 是OnDateChangedListener 和OnTimeChangedListener。
显示时钟的组件AnalogClock/DigitalClock:AnalogClock 用表盘方式显示当前时间,有时针和分针两个指针;DigitalClock 用数字方式显示当前时间,可以显示时、分、秒。
进度条ProgressBar,用来显示任务或工作的完成率,Android 系统中可以实现圆形或者水平的进度条。ProgressBar 类中有setProgress 和getProgress 方法用来设置及获取当前进度,ProgressBar 类中有setSecondaryProgress 和getSecondaryProgress 方法用来设置及获取二级进度。
拖动条SeekBar 是ProgressBar 的子类,使用方式和ProgressBar 类似,拖动条滑动的相关事件接口是OnSeekBarChangerListener。该接口中3 个方法:onProgressChanged 滑动滑杆、onStartTrackingTouch 按住滑杆和onStopTrackingTouch 松开滑杆。 评分条RatingBar,用来实现评分功能。RatingBar 常用的布局属性:android:numStars 用于评分的五角星数,android:rating 指定当前的分数,android:stepSize 指定分数的增量单位,style 设置RatingBar 的风格。
网格组件GridView,以网格的形式排列所包含的内容,每个单元格的内容可以是任意一个View 组件,与ListView 相同。GridView 通过ListAdapter 封装后台的数据,必须调用setAdapter()方法将GridView 和数据绑定,GridView 可以使用OnItemClickListener 及OnItemSelectedListener监听事件。
循环显示组件Gallery,用于显示水平滚动的列表数据,其中心是固定不动的。Gallery 常常用来显示图像列表,也被称为相册组件。Gallery 和GridView 的区别是Gallery 只能显示一行,而且支持水平滑动效果。
标签组件TabHost 是标签的集合,每一个标签是一个TabHost.TabSpec 类的一个实例。
TabHost 类的addTab 方法可以添加多个TabHost.TabSpec 实例,创建TabHost 对象时,一般使用从TabActivity 类继承。

任务实现

1.创建注册界面
在res\layout 中创建activity-regrster.xml,在activity-regrster.xml 文件中根据页面要求设置TextView、EditText、RadioGroup、RadioButton、ToggleButton、CheckBox、Spinner、Button等控件。

图像说明文字

图像说明文字

图像说明文字

图像说明文字

图像说明文字

2.实现注册功能
创建RegisterActivity,在RegisterActivity 中使用findViewById()方法加载各项控件,并实现“注册”按钮的单击事件。在注册按钮事件中将注册信息以字符串形式写入Bundle 对象当中,并通过Intent 跳转到ResultActivity 当中。

图像说明文字

图像说明文字

3.实现登录页面向注册页面的跳转
在LoginAcitivity 中实现注册按钮事件的响应,并利用Intent 实现页面跳转。
在onCreate()方法中添加事件监听方法,代码如下。

btnReg.setOnClickListener(this);

在 onClick(View arg0)方法中实现事件监听,代码如下。

图像说明文字

4.创建结果页面
在res\layout 中创建结果页面result.xml,在该页面中设置listView 控件。

图像说明文字

5.实现结果显示
创建ResultActivity,用于显示用户注册结果,设置activity_result 为显示界面,并加载activity_result.xml 中的listview 控件,通过Intent 接收LoginActivity 传递过来的信息,然后利用ArrayAdapter 适配器显示用户注册信息。具体实现代码如下所示。

图像说明文字

图像说明文字

6.配置AndroidManifest.xml 文件
在AndroidMainfestxml 注册RegisterActivity 与ResultActivity。在AndroidMainfestxml 文件的元素中添加两个元素,内容如下。
< activity android:name="com.siit.dict.RegisterActivity"/>
< activity android:name="com.siit.dict.ResultActivity"/>

任务2.4 用户访问信息存取

任务描述

在dict 工程中编程实现用户登录访问信息的存取,通过Sharedpreferences 方式实现用户名、登录次数和最近登录时间的存取,效果如图2-17 所示。

图像说明文字

任务目标

① 理解SharedPreferences 的概念。
② 掌握使用SharedPreferences 的常用方法掌握File 存取的方法。
③ 会利用SharedPreferences 与File 实现数据的写入和存取。

任务分析

本任务主要实现将用户登录信息的写入SharedPreferences 文件中,并通过菜单单击事件从SharedPreferences 文件中读取用户信息,并显示用户登录信息,具体实现过程如下。
① 将用户登录信息写入SharedPreferences。
② 从SharedPreferences 文件中读取用户登录信息。
③ 实现从LoginActivity 到UserloginInfoActivity 的跳转。
④ 配置AndroidManifest.xml 文件。

知识要点

Android 平台提供的SharedPreferences 类是一个轻量级的存储类,适用于保存软件配置参数。此外Android 也可以像Java 程序一样存入和读取File 文件的内容,下面介绍这两类文件的操作方法。
1.SharedPreferences 文件管理
使用SharedPreferences 保存数据, 其背后使用xml 文件存放数据, 文件存放在/data/data/< package name>/shared_prefs 目录下。
(1)sharedPreferences 文件的创建与存取
有3 种方法可以获取Preferences 文件,下面来分别介绍。

  • this.getPreferences (int mode):通过Activity 对象获取,获取的是本Activity 私有的Preference,保存在系统中的xml 形式的文件的名称为这个Activity 的名字,因此一个Activity 只能有一个Preferences 文件属于该Activity。Activity 提供了getPreferences(mode)方法操作SharedPreferences,这个方法默认使用当前类不带包名的类名作为文件的名称。
  • PreferenceManager.getDefaultSharedPreferences(this):PreferenceManager 的静态函数,保存PreferenceActivity 中的设置,属于整个应用程序,但是只有一个Android 会根据包名和PreferenceActivity 的布局文件来起一个名字保存。
  • this.getSharedPreferences (String name, int mode):因为Activity 继承了ContextWrapper,因此也是通过Activity 对象获取,但是属于整个应用程序,可以有多个。SharedPreferences通过Activity 自带的getSharedPreferences(name,mode)方法指定文件,如果是第一次运行则先创建该文件。getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android 自动加上;方法的第二个参数指定文件的操作模式,共有4 种操作模式。

SharePreferences 操作文件的4 种模式:

  • Context.MODE_PRIVATE=0
  • Context.MODE_APPEND=32768
  • Context.MODE_WORLD_READABLE=1
  • Context.MODE_WORLD_WRITEABLE=2

Context.MODE_PRIVATE:默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下写入的内容会覆盖原文件的内容。
Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。如果想把新写入的内容追加到原文件中,可以使用Context.MODE_APPEND。
Context.MODE_WORLD_READABLE 和Context.MODE_WORLD_WRITEABLE 用来控制其他应用是否有权限读写该文件。
MODE_WORLD_READABLE:表示当前文件可以被其他应用读取。
MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
如果希望SharedPreferences 背后使用的xml 文件能被其他应用读和写,可以指定Context.MODE_WORLD_READABLE 和Context.MODE_WORLD_WRITEABLE 权限。
(2)SharedPreferences 文件内容的编辑与存取 SharedPreferences 类中的edit()方法用于对SharedPreferences 文件内容进行编辑。Editor 类putXXX()方法用于数据的存入,使用Preferences 的键值对存储方式,这种方式主要用来存储比较简单的一些数据,而且是标准的Boolean、Int、Float、Long、String 等类型。
Editor 类的commit()方法用于向sharedPreferences 提交修改。
下面的代码实现将一个随机数的存入到sharedPreferences 文件当中。

图像说明文字

生成的dict.xml 文件内容如下。

图像说明文字

SharedPreferences 文件内容的读取,首先指定并打开Preferences 文件,然后通过getXXX( )方法读取文件内容,代码示例如下。

图像说明文字

2.Android 中使用File 文件
Android 中使用File 文件进行数据存储。有时候可以将数据直接以文件的形式保存在设备中,如文本文件、图片文件等。使用File 进行存储操作主要使用以下方法。

  • public abstract FileInputStream openFileInput (String name):主要是打开文件,返回FileInputStream。
  • public abstract FileOutputStream openFileOutput (String name, int mode):主要是写入文件,如果该文件不存在,直接进行创建,返回FileOutputStream。

Mode 主要有4 种模式:MODE_APPEND 在尾部追加、MODE_PRIVATE 私有、MODE_WORLD_READABLE 可读、MODE_WORLD_WRITEABLE 可写。
FileInputStream(获取文件输入流)与FileOutputStream (获取文件输出流)这两类在JavaIO 操作中很常见,接下来进行操作保存成功之后,文件保存在当前应该程序的包名下的files/(可以改变存储的其他路径)如图2-18 所示,具体代码参见任务实现内容。

图像说明文字

任务实现

1.将用户登录信息写入SharedPreferences
用户单击“登录”按钮时,将用户登录信息写入SharedPreferences。用户登录信息包括用户名、登录次数、最近登录时间。
① 编写saveLoinginfor()方法实现将用户登录信息写入SharedPreferences。

图像说明文字

图像说明文字

② 在“登录”按钮的单击事件中调用saveLoinginfor()实现用户信息写入。相关代码如下。

图像说明文字

2.从SharedPreferences 中读取用户登录信息
① 在res\layout 中创建activity_userloginfo.xml,实现用户登录信息显示页面设计。

图像说明文字

图像说明文字

② 创建UserloginInfoActivity,将activity_userloginfo.xml 文件中的控件使用findViewById()方法加载到该Activity 当中,并读取SharedPreferences 文件中信息,如用户名、登录次数、最近登录时间,将其显示到页面当中。

图像说明文字

图像说明文字

3.实现用户登录页面到用户访问信息页面的跳转
在LoginActivity 中实现菜单事件,先修改aboutuserinfo(String msg)方法,在方法中实现Intent 跳转,并在用户登录页面的菜单事件中调用该方法,相关代码如下。

图像说明文字

4.配置AndroidManifest.xml 文件
< activity android:name="com.siit.dict. UserloginInfoActivity"/>

技能训练

通过SharePreferences 实现当前时间、一个随机数和登录次数的存取。通过File 文件实现数据存取如图2-19 所示。

图像说明文字

在Activity 中生成当前时间、一个随机数和登录次数,单击“写入”按钮通过Shareferences 进行数据保存,单击“读取”按 钮是从Shareferences 中获取写入时间、生成的随机数和登录次数,并使用Toast 将信息显示。从EditText 中写入数据,单击“写入”按钮时将EditText文本框中的文字保存到File 当中去,单击“读取”按钮将File文件的内容读取,并显示到TextView 控件中。

任务2.5 单词存取

任务描述

利用SQLiteDatabase 和SQLiteOpenHelper 类实现单词信息的添加、删除、修改和查询。其中一个界面实现单词管理,包括单词的添加、更新、删除,“单击查看”后,另一个界面用列表显示单词数据,其效果如图2-20 所示。

图像说明文字

任务目标

① 掌握SQLiteDatabase 数据库和数据表的创建。
② 掌握SQLiteDatabase 类的常用方法。
③ 理解SQLiteOpenHelper 类的概念。
④ 掌握SQLiteOpenHelper 类的常用方法。

任务分析

本任务主要实现单词信息的管理,包括单词的添加、删除、修改和查询。单词的数据表结构如图2-21 所示,任务完成后的数据如图2-22 所示。具体实现过程如下所示:
① 准备字符串资源文件;
② 数据层设计与实现;
③ 实现单词管理界面;
④ 实现单词管理;
⑤ 实现单词查询结果显示;
⑥ 实现登录页面向单词管理页面的跳转;
⑦ 配置AndroidManifest.xml 文件。

图像说明文字

知识要点

SQLite 是一款轻量级的关系型数据库。由于它占用的资源非常少,所以Android 系统中用SQLite 来存储数据。SQLiteDatabase 与SQLiteOpenHelper 是Android 系统中用于管理SQLite数据库的类。
1.SQLiteDatabase 简介
Android 平台内置了对SQLite 数据库,它是轻量级的嵌入式数据库。对于数据结构较为复杂的关系型数据,使用SQLite 存储将非常高效。应用程序创建的数据库文件存储在/data/data/包名/database 目录下,应用程序之间不能相互访问。
(1)创建SQLiteDatabase 数据库
Context.openOrCreateDatabase(String name,int mode,CursorFactory factory)

  • name 代表数据库的名称。
  • mode 代表创建数据库的模式,包括MODE_PRIVATEMODE_WORLD_READABLE和MODE_WORLD_WRITEABLE。

使用openOrCreateDatabase()之前要首先查询数据库是否已经存在,效率较低。
(2)创建SQLite 数据表的方法
execSQL(create table _id INTEGER primary key,word text,detail text);
(3)SQLiteDatabase 数据插入
方法一:insert(databaseHelper.DATABASE_TABLE, null, content)。
参数说明:

  • 第一个参数databaseHelper.DATABASE_TABLE 数据库表名;
  • 第二个参数如果content 为空时则向表中插入一个null;
  • 第三个参数为插入的内容。

方法二:execSQL(String sql),sql 为实现数据插入的SQL 命令字符串。
(4)SQLiteDatabase 数据删除
方法一:delete(databaseHelper.DATABASE_TABLE,KEY_ROWID +"="+rowId , null)。

  • 第一参数databaseHelper.DATABASE_TABLE 为数据库表名。
  • 第二个参数KEY_ROWID +"="+rowId 表示条件语句。
  • 第三个参数可表示为条件带?号的表达式。

delete()方法返回值大于0 表示删除成功。
方法二:execSQL(String sql),sql 为实现数据删除的SQL 命令字符串。
(5)SQLiteDatabase 数据修改
方法一:update(databaseHelper.DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null)。

  • 第一个参数databaseHelper.DATABASE_TABLE 表示数据库表名。
  • 第二个参数args 表示更新的内容。
  • 第三个参数KEY_ROWID + "=" + rowId 表示更新的条件。
  • 第四个参数可表示为条件带?号的表达式。

update()方法返回值大于0 表示删除成功。
方法二:execSQL(String sql),sql 为实现数据修改的SQL 命令字符串。
(6)SQLiteDatabase 数据查询
SQLiteDatabase 提供了Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)方法来实现查询记录。 参数介绍:

  • table 代表查询的数据表;
  • columns 代表要查询的列数组;
  • selection 代表查询的条件,可以使用“?”通配符;
  • selectionArgs 代表selection 表达式中的?号;
  • groupBy 代表数据分组;
  • having 代表哪些行显示;
  • orderBy 代表排序的方式。

2.Cursor 类
Cursor 类用于对数据库查询的结果进行随机的读写访问。默认情况下Cursor 的游标位于返回的所有数据行的前面。
Cursor 常用方法如下。

  • move(int offset):将当前游标移动offset 个位置。
  • moveToFirst():将游标移动到第一行。
  • moveToLast():将游标移动到最后一行。
  • isLast():判断游标是否在最后一行。
  • isFirst():判断游标是否在第一行。
  • getPosition():获得游标当前所在行的位置。
  • getCount():获得cursor 中的所有行数。

3.SQLiteOpenHelper 类
使用SQLiteOpenHelper 创建数据库不会重复执行数据库的初始化操作,不需要查询数据库是否存在,执行效率更高。SQLiteOpenHelper 是一个抽象类,需要实现如下方法。

  • onCreate(SQLiteDatabase db)
  • onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)

调用SQLiteOpenHelper 类的getReadableDatabase()方法可以获得一个只读的SQLite Database 对象。
SQLiteDatabase db = SQLOpenHelper.getReadableDatabase();
调用SQLiteOpenHelper 类的getWritableDatabase()方法可以获得可写的SQLiteDatabase 对象。
SQLiteDatabase db = SQLOpenHelper.getWriteableDatabase();
4.SimpleCursorAdapter 简介
public SimpleCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to,intflags)为该适配器类标准的构造函数。
参数如下所述。

  • context:应用程序上下文,具体来说就是ListView 所在的上下文档中。
  • layout:布局文件的资源定位标识符,也就是说标识了ListView 中的item,那么这个布局文件至少包含了参数“to”中的传进来值。
  • c:数据库游标,如果游标不可用则为null。
  • from:列名字列表,表示要绑定到UI 上的列。如果游标不可用则为null。
  • to:展示参数“from”中的列,也就是说ListView 中的视图显示的是参数“from”的列值,这些视图应该都是TextView。如果游标不可用则为null。
  • flags:这个标志用来决定该适配器的行为。设置标志用来添加一个监听器,监听着参数cursor 的数据是否有改变。

任务实现

1.准备字符串资源文件
在res/values/strings.xml 中添加以下字符串资源,供程序调用。

图像说明文字

2.数据层设计与实现
创建WordDBHelper,该类继承于SQLiteOpenHelper 类。通过SQLiteDateBase 与SQLiteOpenHelper 实现数据库的创建、表的创建,定义数据的增加、删除、修改和查询等方法。

图像说明文字

图像说明文字

图像说明文字

3.单词管理界面
使用activity_word.xml 实现单词管理界面的设计。

图像说明文字

图像说明文字

图像说明文字

4.实现单词管理
使用WordManageActivity 实现界面显示,获取文本值并对相应的按钮进行事件响应。

图像说明文字

图像说明文字

图像说明文字

5.实现单词查询结果显示
①界面设计row.xml 用于实现查询内容的显示。

图像说明文字

图像说明文字

② 使用QueryActivity.java 实现查询数据的显示。

图像说明文字

6.实现登录页面向单词管理页面的跳转
在LoginAcitivity 登录按钮的单击事件中利用Intent 实现向单词管理页面的跳转,在onClick(View arg0)方法中的case R.id.regButton:中实现事件监听,添加如下代码。

图像说明文字

7.配置AndroidManifest.xml 文件

图像说明文字

技能训练

1.结合SQLite 实现用户查询与用户注册功能
界面设计如图2-23 所示。

图像说明文字

数据表创建:在WordDBHelper 中通过CREATE_SQLuser 定义“用户信息表”的创建语句,并在onCreate 方法中使用db.execSQL(CREATE_SQLuser)实现用户信息表的创建,用户数据表的结构如图2-24 所示,其数据添加成功后数据表中内容如图2-25 所示。
注册功能:在WordDBHelper 中定义方法int insertUser(String username, String password,String ssex,boolean marrage, String favorite,String position),定义Content cv 对象,通过SQLite的db.insert("usertable", null, cv)方法实现用户信息的注册,添加成功显示用户注册成功。
登录功能:在WordDBHelper 中定义方法Cursor queryUserByname(String username,Stringpassword)通过SQLite 的query()方法验证用户名和密码是否正确,存在该用户名和密码则显示登录成功,否则显示“用户名或密码不正确”。
在登录和注册页面中分别调用insertUser()和queryUserByname()方法实现用户登录验证和用户注册。

图像说明文字

2.利用SQLite 数据库的查询功能实现单词查看
默认显示单词信息的第一条数据,单击“上一条”和“下一条”实现单词信息的滚动显示。界面效果如图2-26 所示,步骤分析如下。

  • 在WordDBHelper 中定义query()方法,用于返回单词信息。
  • 在WordShowActivity 通过WordDBHelper 对象调用query()方法实现单词信息的查询,通过moveToFirs()显示第一条数据,moveToPrevious()查看上一条,moveToNext()查看下一条数据。
  • 单击“编辑单词”跳转到WordManageActivity 页面。

图像说明文字

任务2.6 单词共享

任务描述

使用ContentProvider 将dict 工程中的单词信息定义为内容提供者,共享给其他应用程序,使得其他应用程序可以访问dict 工程当中的数据。创建CPTest 工程,在CPTest 应用程序中通过ContentProvider 读取dict 工程中的单词信息,并逐条显示。
功能效果如图2-27 和图2-28 所示。

图像说明文字

任务目标

① 了解ContentProvider 的概念。
② 知道ContentProvider 的作用。
③ 掌握ContentProvider 的声明与定义过程。
④ 能熟练使用ContentProvider 实现单词的添加、删除、修改。
⑤ 能实现不同应用间的内容共享。

知识要点

1.ContentProvider 简介
ContentProvider 在Android 系统中的作用是对外共享数据,可以通过ContentProvider 把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对应用中的数据进行增、删、改、查。
定义ContentProvider 时需要定义一个类继承自ContentProvider 类,并重写该类的方法。
虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同。例如:
采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences 共享数据,需要使用sharedpreferences API 读写数据。而使用ContentProvider 共享数据的好处是统一了数据访问方式。对于ContentProvider 基本操作分为两个部分,第一定义ContentProvider,第二使用ContentProvider。其中Uri 是ContentProvider 使用过程中的重要概念。
2.Uri 的定义与解析
在ContentProvider 的定义和使用之间利用Uri 进行传递操作指令,所以先介绍Uri 的概念,便于理解ContentProvider 的定义和使用。Uri 代表了要操作的数据,主要包含了两部分信息。
① 需要操作的ContentProvider 。
② 对ContentProvider 中的什么数据进行操作。
一个Uri 由以下几部分组成。

  • ContentProvider(内容提供者)的Scheme 已经由Android 所规定,Scheme 为content://主机名(或叫Authority),用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
  • 路径(path)可以用来表示要操作的数据,路径的构建应根据业务而定。

要操作word 表中id 为10 的记录,可以构建这样的路径:/word/10。
要操作word 表中id 为10 的记录的name 字段,可以构建路径:word/10/name 。
要操作word 表中的所有记录,可以构建路径:/word。
要操作xxx 表中的记录,可以构建路径:/xxx。
要操作的数据不一定只有数据库文件,也可以是文件、xml 或网络等其他形式的内容。
要操作xml 文件中word 节点下的name 节点,可以构建路径:/word/name。
如果要把一个字符串转换成Uri,可以使用Uri 类中的parse()方法。
Uri uri = Uri.parse("content://com.siit.dict.DictProvider/word")
因为Uri 代表了要操作的数据,所以经常需要解析Uri,并从Uri 中获取数据。Android系统提供了两个用于操作 Uri 的工具类,分别为UriMatcher 和ContentUris。掌握它们的使用,有利于开发工作。

  • UriMatcher 类用于匹配Uri,它的用法如下。 ① 首先把需要匹配Uri 路径全部给注册上。
    常量UriMatcher.NO_MATCH 表示不匹配任何路径的返回码。UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH); 如果match()方法匹配content://com.siit.dict.DictProvider/word 路径,返回匹配码为1,sMatcher.addURI("com.siit.dict.DictProvider", "word", 1)。添加需要匹配uri,如果匹配就会返回匹配码。如果match()方法匹配content:// com.siit.dict.DictProvider/word/230 路径,返回匹配码为22,sMatcher.addURI("com.siit.dict.DictProvider", "word /#", 2);//#号为通配符。

图像说明文字

② 注册完需要匹配的Uri 后,在数据的操作方法中(如insert()、delete()、update()、query())就可以使用sMatcher.match(uri)方法对输入的Uri 进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content://com.example. provider.DictProvider/word路径,返回的匹配码为1。

图像说明文字

  • ContentUris 类用于获取Uri 路径后面的ID 部分,它有两个比较实用的方法。
    ① withAppendedId(uri, id)用于为路径加上ID 部分:
    Uri uri = Uri.parse("content://com.siit.dict.DictProvider/word")
    Uri resultUri = ContentUris.withAppendedId(uri, 10);
    生成后的Uri 为:content://com.siit.dict.DictProvider/word/10")。
    ② parseId(uri)方法用于从路径中获取ID 部分:
    Uri uri = Uri.parse("content:// com.siit.dict.DictProvider/word/10")
    long personid = ContentUris.parseId(uri);//获取的结果为:10。

3.ContentProvider 的定义
当应用需要通过ContentProvider 对外共享数据时,第一步需要继承ContentProvider 并重写下面方法。

图像说明文字

下面列出删除方法delete( )的实现代码。其他方法的实现思路也与删除方法类似。具体内容详见任务实现的代码。

图像说明文字

ContentProvider 类的主要方法及其作用如下。

  • public boolean onCreate() 该方法在ContentProvider 创建后就会被调用,Android 开机后ContentProvider 在其他应用第一次访问时会被创建。
  • public Uri insert(Uri uri, ContentValues values) 该方法用于供外部应用向ContentProvider添加数据。
  • public int delete(Uri uri, String selection, String[] selectionArgs) 该方法用于供外部应用从ContentProvider 删除数据。
  • public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 该方法用于供外部应用更新ContentProvider 中的数据。
  • public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 该方法用于供外部应用从ContentProvider 中获取数据。
  • public String getType(Uri uri) 该方法用于返回当前Uri 所代表数据的MIME 类型。

第二步需要在AndroidManifest.xml 的< application > 结点中使用 对该ContentProvider 进行配置。为了能让其他应用找到该ContentProvider,ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,可以把ContentProvider 看作是一个网站,authorities 就是域名。

图像说明文字

4.ContentProvider 的使用
ContnetResolver 是用来操作ContentProvider 中的数据,Context 提供getContentResolver()方法来获取ContentResolver 对象。
getContentResolver()一旦在程序中获得ContentResolver 对象之后,接下来就可以调用ContentResolver 如下方法来操作数据。
Insert(Uri uri,ContentValues values):根据Uri 插入values 对应的数据。
Delete(Uri uri,String selection,String[ ] selectionArgs):根据Uri 删除select 条件所匹配的全部记录。
Update(Uri uri,ContentValues values,String selection,String[ ] selectionArgs):根据Uri修改select 条件所匹配的全部记录。
Query(Uri uri,String[ ] projection,String selection,String[ ] selectionArgs,String sortOrder):根据Uri 查询出select 条件所匹配的全部记录,其中projection 就是一个列名列表,表明只选择出指定的数据列。
5.AndroidManifest 文件中的< provider>元素
Content Provider 是ContentProvider 的子类,它为应用程序管理的数据提供结构化的访问方式。应用程序的所有Content Provider 都必须在AndroidManifest.xml 文件的< provider >元素中定义,否则系统不会运行Content Provider。下面介绍< provider >元素的内容。
android:name 属性指向Provider 类的定义包名和类名,在本任务中的DictProvider 所属包名为com.siit.dict,因此声明android:name="com.siit.dict. DictProvider "。
android:authorities 属性表示一个或多个URI authority 列表,标识了Content Provider 内提供的数据。多个authority 名称之间用分号分隔。为了避免冲突authority 名称应该使用Java风格的命名规则(比如com.siit.dict. DictProvider)。一般来说,它是实现Content Provider 的ContentProvider 子类名,没有默认值至少必须指定一个 authority。只需要声明本应用程序所含的 Content Provider 即可。属于其他应用程序而本程序会用到的 Content Provider 不需要进行声明。
android:exported 表示本 Content Provider 能否被其他应用程序使用,“true”为可以, 任何应用程序都可以通过URI 访问本Content Provider,且受限于Content Provider 声明的权限要求;“false”为不可以,通过设置android:exported="false",可以限制对本应用程序中的 Content Provider 进行。只有用户 ID 相同的应用程序才能访问到它。

任务分析

1.定义ContentProvider
在dict 工程中定义ContentProvider,将dict 工程中的内容共享给其他应用程序访问。
① 定义常量类Words。
② 定义继承自ContentProvider 的DictProvider 类。
③ 在AndroidManifest.xml 中声明DictProvider。
2.实现不同应用间的内容共享
创建CPTest 工程,在该工程中引用Dict 的ContentProvider 实现不同应用间的内容共享。
① 定义常量类Words。
② 定义ContentResolver 实现单词查询。

任务实现

1.定义ContentProvider
(1)定义常量类Words
定义常量类Words,该类主要是用来声明一些常量,如表名、列名、排序URI 和内容类型等。

图像说明文字

图像说明文字

(2)定义继承自ContentProvider 的DictProvider 类
定义DictProvider 类继承自ContentProvider,实现其抽象方法来操作数据库。该类通过创建WordDBHelper 对象来获得数据库实例,引用UriMatcher 工具类来对URI 进行匹配比较,引用HashMap 保存查询列,在onCreate 方法中实例化DBHelper 获得数据实例。用insert()方法实现插入数据,delete()方法实现删除数据,query()方法实现查询数据,update()方法实现更新数据。

图像说明文字

图像说明文字

(3)在AndroidManifest.xml 中声明DictProvider
在AndroidManifest.xml 文件定义< provider >元素,内容如下。

图像说明文字

2.实现不同应用间的内容共享
创建CPTest 工程,在该工程中通过ContentProvider 获取dict 工程的内容,并在CPTest工程中实现对dict 当中单词信息的查询。
(1)定义常量类Words
定义常量类Words,该类主要是用来声明一些常量,如表名、列名、排序URI 和内容类型等。该类中声明AUTHORITY = com.example. provider. DictProvider 是用于ContentResolver中的URI 地址设置。注意必须AndroidManifest.xml 中声明的一致。

图像说明文字

图像说明文字

(2)创建ContentResolver 实现单词的查询
创建WordShowActivity,通过ContentResolver 调用DictProvider 的单词内容,实现对单词查询功能,通过ContentResolver 调用query 实现单词查看功能。

图像说明文字

图像说明文字

图像说明文字

拓展学习

使用ContentProvider 实现通信录功能的设计与实现。通信录功能包括:编号、姓名、电话、电子邮件,设计应用程序实现通信录的添加、删除、修改和查询。

任务 2.7 用户信息网络传输

任务描述

使用Apache Http 方法实现Android 客户端和Web 服务器端的数据交互,并通过Android客户端向Web 服务器端发送数据,实现用户登录和用户注册的功能,如图2-29 所示,数据添加成功后在MySQL 中的数据显示如图2-30 所示。

图像说明文字

任务目标

① 理解Apache Http 方式下Android 客户端与Web 服务器端的请求响应机制。
② 掌握Android 客户端的网络请求响应处理。
③ 掌握Web 服务器端利用Servlet 实现请求响应处理的机制。

任务分析

1.Web 服务器端的操作
① 使用MySQL 实现用户表的设计与创建。
② 连接数据库实现用户登录与注册的数据处理方法。
③ 服务器端登录与注册功能的HttpServlet 设计与实现。
2.Android 客户端的操作
① 使用Apache Http 方法连接网络。
② 实现用户登录和注册功能的请求。

知识要点

为了处理客户端向Web 站点的请求,Apache 开源组织提供了一个HttpClient 项目,该项目是一个简单的HTTP 客户端,可以用于发送HTTP 请求,接收HTTP 响应。Android 已经集成了HttpClient,开发人员可以直接在Android 中使用HttpClient 来访问提交请求、接收响应。下面介绍Apache HttpClient 实现网络数据请求与响应的相关内容。
1.使用Apache HttpClient 访问网络的基本步骤
创建HttpGet 或HttpPost 对象,将要请求的URL 通过构造方法传入HttpGet 或HttpPost对象。
使用DefaultHttpClient 类的execute 方法发送HTTP GET 或HTTP POST 请求,并返回HttpResponse 对象。
通过HttpResponse 接口的getEntity 方法返回响应信息,并进行相应的处理。如果使用HttpPost 方法提交HTTP POST 请求,还需要使用HttpPost 类的setEntity 方法设置请求参数。
Web 服务器和Android 客户端之间网络数据传输过程如图2-31 所示。

图像说明文字

2.HTTP 中 Get 与Post 方法的区别
表单提交中Get 和Post 方法的区别有以下5 点。
① Get 是从服务器上获取数据,Post 是向服务器传送数据。
② Get 是把参数数据队列加到提交表单的ACTION 属性所指的URL 中,值和表单内各个字段一一对应,在URL 中可以看到。Post 是通过HTTP post 机制,将表单内各个字段与其内容放置在HTML HEADER 内一起传送到ACTION 属性所指的URL 地址。用户看不到这个过程。
③ 对于Get 方式,服务器端用Request.QueryString 获取变量的值;对于Post 方式,服务器端用Request.Form 获取提交的数据。
④ Get 传送的数据量较小,不能大于2KB;Post 传送的数据量较大,一般被默认为不受限制。但理论上,IIS4 中最大量为80KB,IIS5 中为100KB。
⑤ Get 安全性非常低,Post 安全性较高。
3.Android 客户端数据请求与响应
(1)定义网络请求及请求地址

图像说明文字

(2)设置传出数据

图像说明文字

(3)执行请求

图像说明文字

(4)接收请求在服务器端的处理结果

图像说明文字

4.Web 服务器端请求与响应
(1)接收请求
定义Servlet 接收请求,重写doGet()与doPost()方法。

图像说明文字

(2)处理请求,传出处理结果

图像说明文字

(3)配置Servlet

图像说明文字

图像说明文字

任务实现

1.Web 服务器端的操作
(1)使用MySQL 实现用户表的设计与创建

图像说明文字

(2)连接数据库实现用户登录与注册的方法
网络服务器端用户登录与注册功能实现,用户登录与注册功能基于Java 的MVC 模式,下面介绍服务器端连接数据库的实现代码。数据库连接工具类DBUtil、用户实体类为User 类、用户数据操作接口UserDao、用户数据操纵的实现类UserDaoImpl。处理用户登录的LoginServlet 类和用户注册的InsertUserServlet 类。数据库连接工具DBUtil 内容如下。

图像说明文字

图像说明文字

DBConfig.properties 文件内容如下。

图像说明文字

用户实体类User 内容如下。

图像说明文字

图像说明文字

图像说明文字

用户数据操作接口UserDao 内容如下。

图像说明文字

用户数据操纵的实现类UserDaoImpl 内容如下。

图像说明文字

图像说明文字

图像说明文字

图像说明文字

图像说明文字

(3)服务器端登录与注册功能的HttpServlet 设计与实现
创建LoginServlet 实现用户登录信息验证。该类继承自HttpServlet,接收Android 客户端发送过来的用户名和密码,结合Web 服务器端的数据处理类实现用户名和密码的验证。如果数据库中存在一条记录和Android 发送过来的信息一致,则返回用户信息,否则返回0。
LoginServlet 功能代码如下。

图像说明文字

用户注册Servlet,接收从Android 端发送过来的用户名、密码、姓名、性别、爱好等信息,并将其添加到数据库中,添加成功返回“用户添加成功”,否则返回“用户添加失败”。

图像说明文字

图像说明文字

图像说明文字

登录和注册功能的web.Xml 中Sevlet 配置如下。

图像说明文字

2.Android 客户端的操作
① 在Android 客户端功能实现用户登录与用户注册,此处主要介绍用户注册和用户登录的方法。
用户登录:从界面获取用户名、密码,通过http 发送到服务器端。

图像说明文字

图像说明文字

② 实现用户注册功能,从界面获取用户名、密码、姓名、性别、爱好,通过HttpClient发送请求,代码如下。

图像说明文字

技能训练

在单词管理WordManageActivity 类中完善单词管理功能,在原有SQLite 数据库单词管理的基础上,利用网络Apache Http 方法实现将Android 客户端的单词添加和单词更新到Web服务器端的MySQL 数据库中,使得SQLite 数据库与服务器端数据库同步,界面效果如图2-32所示,Web 服务器端的数据如图2-34 所示。

图像说明文字

任务2.8 单词网络下载

任务描述

分别使用JSON 和XML 文件将Web 服务器端数据库中的单词信息通过移动互联网传输至Android 客户端,在Android 客户端利用JSON 和XML 文件方式解析服务器端单词信息,并使用列表将单词信息显示到界面当中。
JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)。
XML 的全称为Extensible Markup Language 可扩展标记语言。
界面和服务器端数据如图2-33 和图2-34 所示。

图像说明文字

图像说明文字

任务目标

① 掌握网络数据传输的过程和实现方法。
② 掌握利用JSON 获取服务器端数据,解析JSON 数据,利用列表展示JSON 数据的方法。
③ 掌握利用XML 获取服务器端数据,解析XML 数据,利用列表展示XML 数据的方法。

任务分析

该任务主要实现Web 服务器端向Andorid 客户端批量传输数据。在Android 客户端使用JSON 格式或者XML 形式将单词信息进行解析和显示,具体实现过程如下。
1.Web 服务器端的操作
① 在Web 端利用MVC 模式实现单词信息查询。
② 在Web 端单词将信息转换为JSON 格式或转换为XML 格式。
2.Android 客户端的操作
① 利用URL 访问Android 互联网。
② 客户端利用JSON 或XML 获取并解析单词信息。
③ 将其显示到界面当中。

知识要点

1.JSON 简介
JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation),是轻量级的文本数据交换格式,具有自我描述性,独立于语言且更易理解。JSON 解析器和JSON 库支持许多不同的编程语言。
JSPON 的基本格式: [{name:value, {name:value, {name:value,…},{{name:value, {name:value,{name:value,…},…]
在Java 中解析JSON 数据,首先需要加载org.json 的jar 包,然后使用JSONArray 获取JSON数组,并利用JSONObject 依次遍历JSON 的每一个对象。解析JSON 的核心语句如下,具体方法参见parseJSON()方法。
生成JSON 数组: JSONArray array=new JSONArray(json);
生成JSON 对象:JSONObject jsonObject=array.getJSONObject(i);
2.XML 简介
XML 的全称为Extensible Markup Language 可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。XML 文件示例:

图像说明文字

能够运用在Android 系统上解析XML 文件的有3 种常用方式:DOM、SAX 和PULL,其中DOM 解析XML 是先把XML 文件读进内存中,再通过接口获取数据,该方法使用相对小的XML 文件,移动设备往往受硬件性能影响,如果XML 文件比较大使用DOM 解析往往效率跟不上;SAX 和PULL 都是采用事件驱动方式来进行解析,在Android 中的事件机制是基于回调函数。
此任务中使用的是DOM 解析方式,XML 文件解析具体思路是:首先利用DocumentBuilderFactory 创建一个DocumentBuilderFactory 实例,再利用DocumentBuilderFactory 创建DocumentBuilder,加载XML 文档(Document),获取文档的根结点(Element),然后获取根结点中所有子节点的列表(NodeList),使用再获取子节点列表中的需要读取的结点。XML在Android 的解析参见文中的parseXML(InputStream inStream)方法。

任务实现

1.Web 服务器端的操作
(1)在Web 端利用MVC 模式实现单词信息查询
创建单词信息实体类、数据处理类和数据传输Servlet。

图像说明文字

图像说明文字

图像说明文字

图像说明文字

图像说明文字

在WordDaoImpl 中用List wordList()方法以列表形式输出用户信息。

图像说明文字

(2)在Web 端将单词信息转换为JSON 格式或XML 格式
定义ListWordServlet 将用户信息以JSON 格式或XML 格式输出。

图像说明文字

图像说明文字

2.Android 客户端的操作
(1)利用URL 访问Android 互联网
在WordShowActivity 类中添加getLastJsonUser()方法。该方法的作用是向指定IP 发送请求,并接收Web 服务器端处理的数据结果。

图像说明文字

(2)客户端利用JSON 或XML 获取并解析单词信息
在Android 客户端获取服务器端的处理结果集,然后利用JSON 解析数据,并使用JSONArray 获取JSON 数组,使用JSONObject 依次遍历JSON 的每一个对象。在WordShowActivity 中添加parseJSON()方法,主要代码如下。

图像说明文字

图像说明文字

在WordShowActivity 中添加parseXML()方法,解析XML 文档内容,主要代码如下。

图像说明文字

(3)将单词信息显示到界面当中
在Android 客户端创建Word 实体类。

图像说明文字

Android 单词显示的Layout 设置wordshow.xml。

图像说明文字

图像说明文字

图像说明文字

图像说明文字

Android 端单词显示界面的WordShowActivity。WordShowActivity 中显示单词信息、单词下载、上一条单词、下一条单词查看,并将JSON 数据插入到SQLite 数据库并显示到界面当中。其中SQLite 数据库已经在任务2.5 介绍,具体内容参见任务2.5 的WordDBHelper。按钮事件处理如下。

图像说明文字

图像说明文字

图像说明文字

数据显示参见QueryActivity。通过DBhelper 的query()方法查询所有的单词,并利用SimpleCursorAdapter 将单词信息显示到列表当中。

图像说明文字

图像说明文字

目录

推荐用户

同系列书

  • 移动应用UI设计

    张晓景 胡克

    本书中通过基础加案例的方式向同学们介绍了Photoshop在手机UI领域中的应用。全书中从UI的基础讲起,针对...

    ¥49.80
  • 移动平台UI交互设计与开发

    陈燕 戴雯惠 魏娜 许伟刚

    本书内容分为设计篇和开发篇,以企业全真项目和经典案例为载体,内容覆盖Photoshop在智能手机应用图标设计、...

    ¥45.00
  • Android移动应用开发项目教程

    李新辉 邹绍芳 陈云志 周昕 吴红娉

      本书通过精心设计的7个工作项目,全程贯彻“做中学”理念,先实践认知,后理论拓展,由浅入深,让读者逐步掌握A...

    ¥46.00
  • Android项目开发入门教程

    张伟华 朱东、伊雯雯

    本书主要围绕Android应用程序开发基础、界面设计、Activity、ContentProvider、数据存...

    ¥35.00
  • Android应用程序设计教程

    李华忠 梁永生 刘涛

      全书共分成8章,主要内容包括Android开发环境构建、Android屏幕布局、Android控件Widg...

    ¥39.80
  • 跨平台的移动Web开发实战(HTML5+CSS3)

    从跨平台的移动Web开发实际应用的角度理解HTML5和CSS3的新元素和新功能,合理选取教学内容。本书设置了8...

    ¥49.80
  • Android移动开发项目式教程(第2版)

    谢景明 钟闰禄 陈长辉 冯敬益 王志球

    本书内容主要包括7 部分,第1 部分讲解搭建Android 开发环境的方法,第2 部分讲解在Android...

    ¥42.00
  • HTML 5移动平台的Java Web实用项目开发

    本书以真实购物网站为项目原型,以购物网站为载体,将购物网站的功能模块合理划分为8个教学单元:导航栏和信息提示设...

    ¥45.00
人邮微信
本地服务
教师服务
教师服务
读者服务
读者服务
返回顶部
返回顶部