您好,欢迎来到抵帆知识网。
搜索
您的当前位置:首页Android平台天气预报widget的设计与实现

Android平台天气预报widget的设计与实现

来源:抵帆知识网
Android平台天气预报widget的设计与实现

诚 信 声 明

我声明,所呈交的毕业论文是本人在老师指导下进行的研究工作及取得的研究成果。据我查证,除了文中特别加以标注和致谢的地方外,论文中不包含其他人已经发表或撰写过的研究成果,也不包含为获得其他教育机构的学位或证书而使用过的材料。我承诺,论文中的所有内容均真实、可信。

毕业论文作者签名: 签名日期: 年 月 日

Android平台天气预报widget的设计与实现

Android平台天气预报widget的设计与实现

摘 要

本文对基于Android平台的widget开发技术进行了分析和研究。先简要介绍了Android开发必备基础知识,再切入软件的具体实现过程。

软件的实现是利用网络接口和Google API获取网络xml文件,然后通过xml文件解析取得城市天气预报信息。最终使用widget制作方法,利用RemoteViews等技术完成桌面部件。 关键词: Android;桌面小部件;天气预报

Android平台天气预报widget的设计与实现

the design and implementation of weather forecasting

widget on Android platform

ABSTRACT

This paper analyses and researches the development technique on the Android platform.It first introduce the basic knowledge that is necessary for Android development.And then it introduce the concrete implementation of the software.

The software uses network interface and Google API to get xml document.Then it parse the document to get the weather information of the city.Finally I use technique such as RemotViews to implement the widget.

Keywords: Android; widget; weather forecast

Android平台天气预报widget的设计与实现

目 录

第1章 绪论 ............................................................................................................................................ 1 1.1 项目背景 ....................................................................................................................................... 1 1.2 研究现状 ....................................................................................................................................... 1 1.3 论文组织 ....................................................................................................................................... 2 第2章 ANDROID开发环境 ................................................................................................................ 3 2.1 ANDROID开发环境搭建流程 ........................................................................................................ 3 2.1.1 安装Eclipse ADT Plugin插件 ............................................................................................. 3 2.1.2 安装Android SDK ................................................................................................................ 4 2.1.3 更新Adroid SDK .................................................................................................................. 5 2.1.4 配置Android模拟器 ............................................................................................................ 6 2.2 开发工具ECLIPSE介绍 ................................................................................................................ 7 第3章 ANDROID程序设计基础 ...................................................................................................... 10 3.1 系统结构 ..................................................................................................................................... 10 3.1.1 应用程序 ............................................................................................................................ 10 3.1.2 应用程序框架 ..................................................................................................................... 11 3.1.3 库和运行环境 ..................................................................................................................... 12 3.2 ANDROID应用程序组成 .............................................................................................................. 12 3.2.1 Avtivity介绍 ......................................................................................................................... 12 3.2.2 Broadcast Intent Receiver介绍 ........................................................................................... 13 3.2.3 Service介绍 ......................................................................................................................... 14 3.2.4 Content Provider介绍 ......................................................................................................... 14 3.2.5 Intent介绍 ........................................................................................................................... 15 3.3 ANDROID应用程序工程文件 ...................................................................................................... 17 第4章 天气预报WIDGET的设计 ................................................................................................... 19 4.1 网络功能实现 ............................................................................................................................. 19 4.1.1 标准Java接口 ................................................................................................................... 19 4.1.2 Apache接口 ......................................................................................................................... 20 4.1.3 使用Java接口连接网络 ................................................................................................... 23 4.2 XML解析的实现 .......................................................................................................................... 23 4.3 制作WIDGET应用程序 .............................................................................................................. 27 4.3.1 源文件组织......................................................................................................................... 29 4.3.2 类之间的协作 ..................................................................................................................... 29 4.3.3 CurrentWeather类的实现 ................................................................................................... 30 4.3.4 edit类的实现....................................................................................................................... 31 4.3.5 WeatherHandle类的实现 .................................................................................................... 31 第5章 相关实现技术与体会 .............................................................................................................. 33

Android平台天气预报widget的设计与实现

5.1 添加WIDGET ............................................................................................................................... 33 5.2 REMOTEVIEWS的局限 ................................................................................................................ 34 5.3 在WIDGET中显示图片 .............................................................................................................. 35 5.4 在ANDROIDMANIFEST.XML中进行权限声明 ........................................................................... 35 5.5 为WIDGET中的按钮设置ONCLICK事件 .................................................................................. 36 5.6 利用BUNDLE实现消息的传递 .................................................................................................. 37 5.7 在APPWIDGETPROVIDER类中获取INTENT的附加信息 .......................................................... 37 5.8 软件使用 ..................................................................................................................................... 38 结论 ........................................................................................................................................................ 41 致谢 ........................................................................................................................................................ 42 参考文献 ................................................................................................................................................ 43

3DII技术研究和应用实现

第1章 绪论

1.1 项目背景

2009年1月7日,工业和信息化部为中国移动、中国电信和中国联通发放3张第三代移动通信牌照,此举标志着我国正式进入3G时代。中国3G正式商用和规模建网,决定了中国基于Android的应用程序开发将会处于一个蓬勃发展时期

Android是Google于07年11月5日宣布的基于Linux平台开源手机操作系统名称,号称是首个为移动终端打造的真正开放和完整的移动软件。 它包括操作系统、用户界面和应用程序 —— 移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍。谷歌与开放手机联盟合作开发了 Android,这个联盟由包括中国移动、摩托罗拉、高通、宏达和 T-Mobile 在内的 30 多家技术和无线应用的领军企业组成。

Android有如下多个优势: 1、开放性

2、强大的Google作为传媒平台 3、较为成熟的Linux系统

4、较强的可移植性和强大的操作性

1.2 研究现状

widget作为桌面上网的新模式,Widget在2007年已形成较大市场规模,并为广告商及创业公司带来新的商机。但是为社交网站开发Widget的软件

- 1 -

3DII技术研究和应用实现

开发人员却表示,Widget的影响力被严重低估。

Android中的Widget是Android 1.5以后加入的一个特性,允许程序显示一些常用而又重要的信息在用户的Home screen(桌面主屏)上。

简单的说就是有两个特点: 一是可以添加到Home screen上, 二是按照一定的时间进行内容更新

以上两点就是由android 系统中的 AppWidget Framework(框架) 来支持完成的。

当最基本的控件,如Clock和Picture Frame Home Screen ,随第一款Android手机的发布后,Android用户就开始尝试编写各种应用Widget(小工具)了,随着Widget API的公开,为开发人员带来了全新有趣的开发模式,除了传统的电话应用外,还可以做其它方面的应用开发。

1.3 论文组织

本文主要在介绍Android widget应用程序开发的要点,以及本人这段时间学习Android开发的体会。本文在第二章介绍Android开发环境的搭建,在第三章介绍Andoid开发基础知识,第四章介绍天气预报桌面小程序的设计与实现,最后一章介绍在软件设计过程中遇到的难题和相应解决方案。

- 2 -

3DII技术研究和应用实现

第2章 Android开发环境

2.1 Android开发环境搭建流程

Android开发首先需要搭建完整的开发环境,由于软件均是基于Dalvik Java Virtual Machine运行的所以Google官方推荐使用主流的Java开发IDE Eclipse。我们需要下载必要的开发组件。

1)Java运行时库(JRE),由于Eclipse使用Java开发,所以需要它才可以正常运行IDE。

2)Eclipse集成开发环境,官方提供的Android开发插件ADT Plugin是基于Eclipse编写的,当然用户可以使用NetBean、JBuilder当作代码编辑器使用,但目前没有完整的调试集成。

3)Eclipse ADT Plugin插件是Android Develop Tool Kit的插件,用户需要安装它才能在Eclipse中建立和调试Android程序。

4)Android SDK,它包含了完整的Android模拟器 、Android开发文档和调试工具,Google官方也会定时更新 2.1.1 安装Eclipse ADT Plugin插件

首先我们将下载的JRE安装。运行Eclipse开发环境。安装Eclipse ADT Plugin,选择【Help】 > 【Soft Updates】 > 【Find and Install„】

选择“Available Software”标签页,点击【Add Site„】按键。添加update站点:https://dl-ssl.google.com/android/eclipse/

- 3 -

3DII技术研究和应用实现

这时窗口中新增了“https://dl-ssl.google.com/android/eclipse/”项,选中该项,点击【Install„】按键即可下载。 2.1.2 安装Android SDK

将安装的Android SDK包解压,运行Eclipse。选择【Window】 > 【Preferences】,选择Android,如下图

点Browse按钮选择SDK解压后的路径。

为了在DOS控制台中直接使用SDK的工具,可以将SDK的目录添加

- 4 -

3DII技术研究和应用实现

到Windows的path环境变量中:在桌面上右击“我的电脑”,依次点击【属性】>【高级】>【环境变量】。双击【系统变量】里面的Path项,将Android SDK中tools目录的完整路径添加到这里。 2.1.3 更新Adroid SDK

Android SDK的升级如此之快让人有点招架不住,为了使用SDK的新特性,有必要将其升级

第一步:

打开Eclipse工具,在工具栏里找到

这个按钮,如果你没有找到也不

要着急,你在菜单栏【Window】 > 【Android SDK and AVD Manager】里也能找到这个按钮,点击之弹出如下对话框:

第二步:

选择Availabe Package这一标签,然后将出现如下对话框(记得要勾选那个复选框):

- 5 -

3DII技术研究和应用实现

然后选择Installed Packages,点击Update ALL按钮即可升级。 2.1.4 配置Android模拟器

(1) 首先打开\"Android SDK and AVD Manager\",如图所示。

(2) 点击左边的\"Virtual Devices\"选项,在点击右边的\"New...\"按钮,来新建一个AVD。

(3) 在\"name\"标签处填写AVD的名字,\"Target\"标签处选择api等级,在

- 6 -

3DII技术研究和应用实现

\"size\"标签处填写要创建的SD卡的大小,在\"skin\"标签中设置模拟器的风格, (4) 到这里,还需要配置模拟器运行的AVD,操作步骤:点击\"Run\",选择\"Open Run Dialog\"菜单命令,打开对话框,如图2-33所示。

(5) 双击\"Run \"对话框左边的导航器中的\"Android Application\"菜单命令,创建一个Android项目运行配置。在右边的\"Name\"文本框中输入 Android项目运行配置的名字,在\"Android\"选项卡中的\"Project\"文本框中输入要运行的Android项目,同样可以点击右边的\"Browse...\"按钮来选择Android项目。

2.2 开发工具Eclipse介绍

Eclipse是一种可扩展的开放源代码IDE。2001年11月,IBM公司捐出价值4,000万美元的源代码组建了Eclipse联盟,并由该联盟负责这种工具的后续开发。集成开发环境(IDE)经常将其应用范围限定在“开发、构建

- 7 -

3DII技术研究和应用实现

和调试”的周期之中。为了帮助集成开发环境(IDE)克服目前的局限性,业界厂商合作创建了Eclipse平台。Eclipse允许在同一IDE中集成来自不同供应商的工具,并实现了工具之间的互操作性,从而显著改变了项目工作流程,使开发者可以专注在实际的嵌入式目标上。

Eclipse框架的这种灵活性来源于其扩展点。它们是在XML中定义的已知接口,并充当插件的耦合点。扩展点的范围包括从用在常规表述过滤器中的简单字符串,到一个Java类的描述。任何Eclipse插件定义的扩展点都能够被其它插件使用,反之,任何Eclipse插件也可以遵从其它插件定义的扩展点。除了解由扩展点定义的接口外,插件不知道它们通过扩展点提供的服务将如何被使用。

利用Eclipse,我们可以将高级设计(也许是采用UML)与低级开发工具(如应用调试器等)结合在一起。如果这些互相补充的工具采用Eclipse扩展点彼此连接,那么当我们用调试器逐一检查应用时,UML对话框可以突出显示我们正在关注的器件。事实上,由于Eclipse并不了解开发语言,所以无论Java语言调试器、C/C++调试器还是汇编调试器

都是有效的,并可以在相同的框架内同时瞄准不同的进程或节点。 Eclipse的最大特点是它能接受由Java开发者自己编写的开放源代码插件,这类似于微软公司的Visual Studio和Sun微系统公司的NetBeans平台。Eclipse为工具开发商提供了更好的灵活性,使他们能更好地控制自己的软件技术。eclipse是一款非常受欢迎的java开发工具,使国内的用户越来越多,实际上使用它的java开发人员是最多的。缺点就是较复杂,对初学者

- 8 -

3DII技术研究和应用实现

来说,理解起来比较困难。

- 9 -

3DII技术研究和应用实现

第3章 Android程序设计基础

3.1 系统结构

Android作为一个移动设备开发平台,其软件层次结构包括了一个操作系统,中间件和应用程序。其框架如下图所示

其软件层析结构自上而下可以分为以下几个层次: 一.应用程序(Application);

二.应用程序框架(Application Framework);

三.各种库(Libraries)和Android运行环境(RuntTime); 四.操作系统层(OS)。 3.1.1 应用程序

Android的应用程序通常涉及用户界面和用户交互,这类程序是用户实

- 10 -

3DII技术研究和应用实现

实在在感受到的。Android的应用程序目前以Java语言编写。Android本身提供桌面,联系人,电话和浏览器等核心应用。同时应用程序开发者可以根据应用程序框架层的API实现自己的程序,这也是Android开源的巨大潜力体现。Android这种开放而强大的平台给每一个程序开发者提供了公平的机会,每一个开发者都可以加入移动互联的世界,共同推动移动互联的发展。

3.1.2 应用程序框架

普通的开发者可以使用Android核心应用程序的系统API。Android的应用开发框架涉及的非常巧妙,通过这套应用框架,各种组件可以被用户的应用重复利用,各种服务也可以被各种应用重复应用。开发人员应该很好地理解这套框架的工作机制,这样才能开发出更好的应用程序。 下面列举应用框架的主要部分:

一.一组Views。这些UI组件包括列表、文本框、按钮等。通过这些UI组件,可以构建应用程序的试图部分,这部分也就是用户能看到的部分。 二.ContentProviders。主要是提供一种机制,通过这种机制,各个应用程序之间可以实现数据的互访和共享。

三.Resource Manager。它负责管理非代码的访问。如本地图片资源,设计布局的XML文件等的访问。

四.Notification Manager。它能让程序的将自己的警示信息显示在状态栏上。例如,当有短信的时候,可以在状态栏上显示新短信的信息。 五.Activity Manager。它管理应用的生命周期,并且提供应用页面退出

- 11 -

3DII技术研究和应用实现

的机制。在Android应用中,一个应用一般都是多个页面组成,而每个页面的单位就是Activity。 3.1.3 库和运行环境

Android包括一些C/C++库,这些库能被Android系统的不同组件使用。他们通过Android应用程序框架为开发者提供服务。

3.2 Android应用程序组成

要进行应用开发,还需要对Android应用构造进行深入的分析。Android应用程序由以下4个模块构造而成: Activity

Broadcast Intent Receiver Service

Content Provider

当然,也不是每个Android应用程序都必须由这4部分组成,它可以根据开发者需求来进行组合 。

在这里还需要介绍Intent的概念和使用方法,他在应用程序的运行中连接两个不同的组件,通过Intent你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来请求。 3.2.1 Avtivity介绍

Activity是最基本的模块。我们称之为\"活动\",在应用程序中,一个活动(Activity)通常就是一个单独的屏幕。每一个活动都被实现为一个的类,并且从活动基类中继承而来,活动类将会显示由视图控件组成的用户接口,并对事件作出响应。大多数的应用都是由多个Activity显示组成,例如,对一个文本信息应用而言,第一个屏幕用来显示发送消息的联系人

- 12 -

3DII技术研究和应用实现

列表,第二个屏幕用来写文本消息和选择收件人,第三个屏幕查看消息历史或者消息设置操作等。

这里的每一个屏幕就是一个活动,很容易实现从一个屏幕到一个新的屏幕,并且完成新的活动。当一个新的屏幕打开后,前一个屏幕将会暂停,并保存在历史栈中。用户可以返回到历史栈中的前一个屏幕,当屏幕不再使用时,还可以从历史栈中删除。

简单理解,Activity代表一个用户所能看到的屏幕,主要用于处理应用程序的整体性工作,例如,监听系统事件(按键事件、触摸屏事件等),为用户显示指定的View,启动其他Activity等。所有应用的Activity都继承于android.app.Activity类,该类是Android提供的基层类,其他的Activity继承该父类后,通过父类的方法来实现各种功能,这种设计在其他领域也较为常见。

3.2.2 Broadcast Intent Receiver介绍

可以使用BroadcastReceiver来让应用对一个外部的时间作出相应。例如,当电话呼入这个外部时间到来的时候,可以利用BroadcastReceiver进行处理。BroadcastReceiver不能生成UI,也就是说对用户是不透明的,用户是看不到的。BroadcastReceiver通过NotificationManager来通知用户这些事情发生了。BroadcastReceiver既可以在AndroiManifest.xml中注册,也可以在运行时的代码使用Context.registerReceiver()进行注册。只要是注册了,当时间来临的时候,即使程序没有启动,系统也在需要的时候启动程序。各种应用程序还可以通过Context.sendBroadcast()将他们自己的intent

- 13 -

3DII技术研究和应用实现

broadcasts广播给其他应用程序。 3.2.3 Service介绍

Service即\"服务\"的意思,既然是服务,那么Service将是一个生命周期长而且没有用户界面的程序。比如一个正在从播放列表中播放歌曲的媒体播放器,在这个媒体播放器应用中,应该会有多个activity,让使用者可以选择歌曲并播放歌曲。然而,音乐重放这个功能并没有对应的activity,因为使用者会认为在导航到其他屏幕时音乐应该还在播放。在这个例子中,媒体播放器这个activity会使用Context.startService()来启动一个service,从而可以在后台保持音乐的播放。同时,系统也将保持这个service一直执行,直到这个service运行结束。另外,我们还可以通过使用Context.bindService()方法连接到一个service上(如果这个service当前还没有处于启动状态,则将启动它)。当连接到一个service之后,还可用service提供的接口与它进行通讯。以媒体播放器为例,我们还可以执行暂停、重播等操作。 3.2.4 Content Provider介绍

Android这个系统和其他的操作系统还不太一样,我们需要记住的是,数据在Android当中是私有的,当然这些数据包括文件数据和数据库数据,以及一些其他类型的数据。一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型,也就是说,一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据暴露出去。外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,即用数据库存储还是文件存储,还是通过网上

- 14 -

3DII技术研究和应用实现

获得,这一切都不重要,重要的是外界可以通过这一套标准而统一的接口和程序里面的数据打交道。可以读取程序数据,也可以删除程序的数据,当然中间会涉及一些权限问题。 3.2.5 Intent介绍

Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来请求。比如,有一个Activity希望打开网页浏览器查看某一网页的内容,那么这个Activity只需要发出WEB_SEARCH_ACTION请求给Android,Android会根据Intent的请求内容,查询各组件注册时声明的IntentFilter,找到网页浏览器Activity来浏览网页。

Android的三个基本组件——Activity,Service和BroadcastReceiver,它们都是通过Intent机制激活的,而不同类型的组件有传递Intent的不同方式。

(1) 要激活一个新的Activity,或者让一个现有的Activity执行新的操作,可以通过调用Context.startActivity()或者Activity.startActivityForResult()方法。这两个方法需要传入的Intent参数也称为Activity Action Intent(活动行为意图),根据Intent对象对目标Activity描述的不同,来启动与之相匹配的Activity或传递信息。

(2) 要启动一个新的服务,或者向一个已有的服务传递新的指令,调用

- 15 -

3DII技术研究和应用实现

Context.startService()方法或调用Context.bindService()方法将调用此方法的上下文对象与Service绑定。

(3) 通过Context.sendBroadcast()、Context.sendOrderBroadcast()和Context.send-StickBroadcast()这三个方法可以发送BroadcastIntent。BroadcastIntent发送后,所有已注册的拥有与之相匹配IntentFilter的BroadcastReceiver就会被激活。这种机制被广泛运用于设备或系统状态变化的通知,一个常见的例子是,当Android的电池电量过低时,系统会发送Action为BATTERY_LOW的广播,接着任何可匹配该Action的IntentFilter注册的BroadcastReceiver都会各自运行自定义的处理代码,比如关闭设备的WIFI和GPS以节省电池消耗。

Intent一旦发出,Android都会准确找到相匹配的一个或多个Activity、Service或Broadcast-Receiver作为响应。所以,不同类型的Intent消息不会出现重叠:BroadcastIntent消息只会发送给BroadcastReceiver,而绝不可能发送给Activity或Service。由startActivity()传递的消息也只可能发送给Activity,由startService()传递的Intent只可能发送给Service。

Intent对象抽象地描述了要执行的操作,其描述的基本内容可以分为组件名称、Action(动作)、Data(数据)、Category(类别)、Extra(附加信息)和Flag(标志位)6部分

Intent分为显式Intent和隐式Intent :

对于明确指出了目标组件名称的Intent,我们称之为“显式Intent”。对

- 16 -

3DII技术研究和应用实现

于没有明确指出目标组件名称的Intent,则称之为“隐式Intent”。Android系统使用IntentFilter 来寻找与隐式Intent相关的对象。

显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,因此,显式Intent更多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。隐式Intent恰恰相反,它不会用组件名称定义需要激活的目标组件,它更广泛地用于在不同应用程序之间传递消息。

3.3 Android应用程序工程文件

典型的工程文件如下图所示:

与一般的Java项目一样,src文件夹是项目的所有包及源文件(.java),res文件夹中则包含了项目中的所有资源,比如:程序图标(drawable)、布局文件(layout)、常量(values)等。下面来介绍其他Java项目中没有的gen文件夹中的R.java文件和每个Android项目都必须有的

- 17 -

3DII技术研究和应用实现

AndroidManfest.xml文件。

R.java是在建立项目时自动生成的,这个文件是只读模式,不能更改,R.java文件是定义该项目所有资源的索引文件。

AndroidManfest.xml文件则包含了该项目中所使用的Activity、Service、Receiver。相当于应用的配置文件,在应用中是一个相当重要的文件。

- 18 -

3DII技术研究和应用实现

第4章 天气预报widget的设计

4.1 网络功能实现

Android可以使用以下两种网络接口 4.1.1 标准Java接口

java.net.*下面提供了访问 HTTP 服务的基本功能。使用这部分接口的基本操作主要包括:

·创建 URL 以及 URLConnection / HttpURLConnection 对象 ·设置连接参数 ·连接到服务器 ·向服务器写数据 ·从服务器读取数据

import java.io.InputStream;

import java.io.OutputStream; import java.net.URL;

import java.net.URLConnection; import java.net.HttpURLConnection; try {

// 创建一个 URL 对象 URL url = new URL(your_url);

// 创建一个 URL 连接,如果有代理的话可以指定一个代理。 URLConnection connection = url.openConnection(Proxy_yours); // 对于 HTTP 连接可以直接转换成 HttpURLConnection, // 这样就可以使用一些 HTTP 连接特定的方法,如 setRequestMethod() 等

//HttpURLConnection connection =

(HttpURLConnection)url.openConnection(Proxy_yours);

- 19 -

3DII技术研究和应用实现

// 在开始和服务器连接之前,可能需要设置一些网络参数 connection.setConnectTimeout(10000);

connection.addRequestProperty(\"User-Agent\ \"J2me/MIDP2.0\"); // 连接到服务器 connection.connect();

// 往服务器写数据,数据会暂时被放到内存缓存区中 // 如果仅是一个简单的 HTTP GET,这一部分则可以省略 OutputStream outStream = connection.getOutputStream(); ObjectOutputStream objOutput = new ObjectOutputStream(outStream);

objOutput.writeObject(new String(\"this is a string...\")); objOutput.flush();

// 向服务器发送数据并获取应答

InputStream in = connection.getInputStream(); // 处理数据 ...

} catch (Exception e) {

// 网络读写操作往往会产生一些异常,所以在具体编写网络应时

// 最好捕捉每一个具体以采取相应措施

} 4.1.2 Apache接口

Apache HttpClient 是一个开源项目,弥补了 java.net.* 灵活性不足的缺点,为客户端的HTTP编程提供高效、最新、功能丰富的工具包支持。Android 平台引入了 Apache HttpClient 的同时还提供了对它的一些封装和扩展,例如设置缺省的HTTP超时和缓存大小等。早期的 Android 曾同时

- 20 -

3DII技术研究和应用实现

包括 Commons HttpClient (org.apache.commons.httpclient.*) 和 HttpComponents (org.apache.http.client.* ),不过当前版本 (1.5) 中开发者只能使用后者,也就是说类似以下的一些类:

使用这部分接口的基本操作与 java.net.* 基本类似,主要包括: ·创建 HttpClient 以及 GetMethod / PostMethod, HttpRequest 等对象 ·设置连接参数 ·执行 HTTP 操作 ·处理服务器返回结果

import org.apache.http.HttpEntity;

import org.apache.http.HttpHost;

import org.apache.http.HttpResponse;

import org.apache.http.auth.AuthScope;

import org.apache.http.auth.UsernamePasswordCredentials;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.conn.params.ConnRoutePNames;

import org.apache.http.params. HttpConnectionParams;

import org.apache.http.client.params. HttpClientParams;

try {

// 创建 HttpParams 以用来设置 HTTP 参数(这一部分不是必需的)

HttpParams params = new BasicHttpParams();

- 21 -

3DII技术研究和应用实现

// 设置连接超时和 Socket 超时,以及 Socket 缓存大小 HttpConnectionParams.setConnectionTimeout(params, 20 * 1000); HttpConnectionParams.setSoTimeout(params, 20 * 1000); HttpConnectionParams.setSocketBufferSize(params, 8192); // 设置重定向,缺省为 true

HttpClientParams.setRedirecting(params, true); // 设置 user agent

HttpProtocolParams.setUserAgent(params, userAgent); // 创建一个 HttpClient 实例

// 注意 HttpClient httpClient = new HttpClient(); 是Commons HttpClient

// 中的用法,在 Android 1.5 中我们需要使用 Apache 的缺省实现 DefaultHttpClient

HttpClient httpClient = new DefaultHttpClient(params);

// 创建 HttpGet 方法,该方法会自动处理 URL 地址的重定向 HttpGet httpGet = new HttpGet (\"http://www.test_test.com/\"); HttpResponse response = client.execute(httpGet);

if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {

// 错误处理,例如可以在该请求正常结束前将其中断 httpGet.abort(); }

// 读取更多信息

Header[] headers = response.getHeaders();

HttpEntity entity = response.getEntity();

Header header = response.getFirstHeader(\"Content-Type\");

- 22 -

3DII技术研究和应用实现

} catch (Exception ee) { //

} finally { // 释放连接

client.getConnectionManager().shutdown();

}

4.1.3 使用Java接口连接网络

本设计使用Java接口从网络获取信息。

在Android应用中,要使用网络必须先在AndroidManifest.xml注册使用网络功能。其xml语句为

我是利用Google提供的Web Service来完成从网络获取天气信息任务的。

首先需要一个URL类表示我们要获取内容的网址

String aStrring=\"http:www.//google.com/ig/api?weather=\"+city; URL aURL=new URL(aString.replace(\" \

通过openStream()方法获取xml信息,将其作为一个参数传给xml解析器进行xml解析。

4.2 xml解析的实现

我是通过利用SAX来实现xml的解析的。 用SAX解析xml,我们需要一个SAXParser对象。 SAXParserFactory spf=SAXParseFactory.newInstance(); SAXParser sp=spf.newSAXParser();

有了SAXParser实例,接下来要想办法读入xml文件。org.xml.sax.XMLReader为我们提供了这样一个借口,它的方法

- 23 -

3DII技术研究和应用实现

setContentHandler允许我们在读入xml之前注册一系列处理器。 /*从SAXParser获取XMLReader*/ XMLReader xr=sp.getXMLReader(); /*创建我们自己的内容处理器*/

ExampleHandler myHander=new ExampleHandler(); /*用内容处理器处理XMLReader*/ xr.setContentHandler(myHandler);

设置好内容处理器之后,就可以开始使用XMLReader读取xml内容,并通过myHandler对象返回从xml中获得的数据. /*XMLReader获取xml文件并进行解析*/ xr.pars(new InputSource(aURL.openStream());

XMLReader会便利读取xml文件中的所有内容,在读取过程中,事先注册好的xml内容处理器就会被依次触发。

要实现xml内容处理器,需要继承类org.xml.sax.helpers.DefaultHandler,它提供了startDocument(),endDocument(),startElement(),endElement(), Charators()等方法。继承DefaultHandler之后需要重写这些方法,一边有效的处理xml内容,其中各个方法被调用的情况如下:

在xml文件开始的地方会调用starDocument()方法,在文件结束的地方会调用endDocument()方法。

Xml中的节点总是以...的方式组织起来的,因此当SAXParser解析到xml开头的tag时,starElement就会被调用。而当SAXParser解析到xml结尾的tag时,endElement就会被调用。

在xml文件中,我们常常在开始tag和结束tag之间放入数据,当

- 24 -

3DII技术研究和应用实现

SAXParser解析到中间数据时,方法charactors()就会被调用。

下面是我根据Google API返回的xml格式重写后的两个方法,startElement()和endElement()。

public void startElement(String namespaceURI, String localName,

String qName, Attributes atts) throws SAXException { // 'Outer' Tags

if (localName.equals(\"forecast_information\")) { this.in_forecast_information = true;

} else if (localName.equals(\"current_conditions\")) { this.in_current_conditions = true;

} else if (localName.equals(\"forecast_conditions\")) { this.in_forecast_conditions = true; } else {

String dataAttribute = atts.getValue(\"data\"); // 'Inner' Tags of \"\" if (localName.equals(\"city\")) {

} else if (localName.equals(\"postal_code\")) { } else if (localName.equals(\"latitude_e6\")) { } else if (localName.equals(\"longitude_e6\")) { } else if (localName.equals(\"forecast_date\")) { } else if (localName.equals(\"current_date_time\")) { } else if (localName.equals(\"unit_system\")) { if (dataAttribute.equals(\"SI\"))

this.usingSITemperature = true; }

// SHARED(!) 'Inner' Tags within \"\" AND

// \"\"

else if (localName.equals(\"day_of_week\")) { if (this.in_current_conditions) {

} else if (this.in_forecast_conditions) { }

} else if (localName.equals(\"icon\")) { if (this.in_current_conditions) {

this.setIconURL(dataAttribute); } else if (this.in_forecast_conditions) {

- 25 -

3DII技术研究和应用实现

}

} else if (localName.equals(\"condition\")) { if (this.in_current_conditions) {

this.setCurrentCondition(dataAttribute); } else if (this.in_forecast_conditions) { } }

// 'Inner' Tags within \"\" else if (localName.equals(\"temp_f\")) { } else if (localName.equals(\"temp_c\")) {

this.setCurrentTemp(Integer.parseInt(dataAttribute)); } else if (localName.equals(\"humidity\")) { this.setCurrentHum(dataAttribute);

} else if (localName.equals(\"wind_condition\")) { //可扩展

}

// 'Inner' Tags within \"\" else if (localName.equals(\"low\")) {

int temp = Integer.parseInt(dataAttribute); if (this.usingSITemperature) { //可扩展 } else { //可扩展

}

} else if (localName.equals(\"high\")) {

//int temp = Integer.parseInt(dataAttribute); if (this.usingSITemperature) { //可扩展 } else { //可扩展 } } } }

@Override

- 26 -

3DII技术研究和应用实现

public void endElement(String namespaceURI, String localName, String qName) throws SAXException {

if (localName.equals(\"forecast_information\")) { this.in_forecast_information = false;

} else if (localName.equals(\"current_conditions\")) { this.in_current_conditions = false;

} else if (localName.equals(\"forecast_conditions\")) { this.in_forecast_conditions = false; } }

4.3 制作widget应用程序

桌面部件widget是一种利用AppWidget框架将应用程序的某个部件摆放在桌面,以便于用户快速了解信息以及操作应用程序的桌面组件,如未完成的日历项、音乐播放器的播放暂停和当前播放音乐的信息等。 要为应用程序定义桌面部件,首先要在应用程序项目的res/xml/目录下新建一个XML文件来对桌面部件进行描述,其描述的信息包括了桌面部件在桌面上所占的空间、更新的周期时间以及部件的布局文件。由于在桌面上所有组件的大小均以单元格为单位,所以这里我们要对桌面部件的最小宽度和最小高度进行描述,然后当桌面部件最终被添加到桌面上时,其大小会被设定为最接近的所占单元格数大小。下面是一个桌面部件的宽或高所占单元格数换算最小尺寸的公式:

最小尺寸=(单元格数×74).2 (单位:dip)

AppWidget框架是通过接收广播Intent的方式来对桌面部件进行控制的,所以每个描述桌面部件的XML文件都有一个对应的广播接收器。为了针对桌面部件不同的状态执行不同的操作,AppWidget框架提供了一个继承自BroadcastReceiver的AppWidgetProvider类。这样我们只需要在应用程序

- 27 -

3DII技术研究和应用实现

中创建一个AppWidgetProvider的子类,然后重新实现不同状态下的回调方法就可以响应AppWidget框架的控制了。

AppWidgetProvider 类扩展BroadcastReceiver 为一个简便类来处理App Widget广播。AppWidgetProvider只接收和这个App Widget相关的事件广播,比如这个App Widget被更新,删除,启用,以及禁用。当这些广播事件发生时,AppWidgetProvider 将接收到下面的方法调用: onUpdate(Context, AppWidgetManager, int[])

这个方法调用来间隔性的更新App Widget,间隔时间用AppWidgetProviderInfo 里的updatePeriodMillis属性定义(参见添加AppWidgetProviderInfo元数据)。这个方法也会在用户添加App Widget时被调用,因此它应该执行基础的设置,比如为视图定义事件处理器并启动一个临时的服务Service,如果需要的话。但是,如果你已经声明了一个配置活动,这个方法在用户添加App Widget时将不会被调用,而只在后续更新时被调用。配置活动应该在配置完成时负责执行第一次更新。(参见下面的创建一个App Widget配置活动Creating an App Widget Configuration Activity。)

onDeleted(Context, int[])

当App Widget从宿主中删除时被调用。 onEnabled(Context)

当一个App Widget实例第一次创建时被调用。比如,如果用户添加两个你的App Widget实例,只在第一次被调用。如果你需要打开一个新的数据库或者执行其他对于所有的App Widget实例只需要发生一次的设置,那么这里是完成这个工作的好地方。

- 28 -

3DII技术研究和应用实现

onDisabled(Context)

当你的App Widget的最后一个实例被从宿主中删除时被调用。你应该在onDisabled(Context)中做一些清理工作,比如删除一个临时的数据库。 onReceive(Context, Intent)

这个接收到每个广播时都会被调用,而且在上面的回调函数之前。 4.3.1 源文件组织

源程序包括三个java类:

一、CurrentWeather类,继承自AppWidgetProvider 类 。使用这个类编程与App Widget连接。这个类当中还有一个UpdateService子类,继承自Service。

二、edit类,继承自Acitivity,用于用户修改要进行天气预报的城市。 三、WeatherHandler类,用于xml的解析 下面说明各个类功能的实现 4.3.2 类之间的协作

当一个widget被添加时,CurrentWeather类会接收action为APPWIDGET_UPDATE的Intent,CurrentWeather会启动一个Service,由这个服务与网络连接,获取天气预报信息,因为获得的数据形式是xml的,所以调用WeatherHandle类进行xml解析,根据解析后的结果将相关信息显示在用户桌面。当用户想改变城市时,点击桌面上的按钮,就会触发绑定在按钮上的PendingIntent,唤醒edit这个Activity,edit类获取用户输入的城市信息后,广播Intent唤醒CurrentWeather对App Widget进行更新。并使用finish()方法关闭本页面。

- 29 -

3DII技术研究和应用实现

4.3.3 CurrentWeather类的实现

首先定义一个私有类变量来保存城市信息,初始化为“guangzhou,china”

private static String city=“guangzhou,china”; 重写了onReceive()方法,如下所示

public void onReceive(Context context,Intent intent) { final String action = intent.getAction();

if(action.equals(AppWidgetManager.ACTION_APPWIDGET_UPDATE)){ Bundle bundle=new Bundle(); bundle=intent.getExtras();

String temp=bundle.getString(\"Data\"); if(temp!=null) { city=temp; }

context.startService(new Intent(context,UpdateService.class)); } }

实现UpdateService的功能: 重写onStart()方法:

首先根据类变量city的值向网络请求数据,并使用WeatherHandler类解析xml得到该城市天气信息。

然后使用RemoteViews更新App Widget:

RemoteViews updateViews = new RemoteViews(getPackageName(), R.layout.weather); updateViews.setTextViewText(R.id.city,city); updateViews.setTextViewText(R.id.tem,\"gwh.getCurrentTemp() + \"摄氏度\");

updateViews.setTextViewText(R.id.weather,gwh.getCurrentCondition()); updateViews.setTextViewText(R.id.hum,\"\"+ gwh.getCurrentHum() );

- 30 -

温度:\" +

3DII技术研究和应用实现

Intent nIntent=new Intent(getApplicationContext(),edit.class); PendingIntent

pIntent=PendingIntent.getActivity(getApplicationContext()

,0,nIntent,0);

updateViews.setOnClickPendingIntent(R.id.btn,pIntent); ComponentName thisWidget=new ComponentName(this,

Current.class);

AppWidgetManager manager = AppWidgetManager.getInstance(this); manager.updateAppWidget(thisWidget, updateViews); 4.3.4 edit类的实现

edit类是一个Activity,主要功能是将用户输入的城市信息放到Intent的extras中,然后将其广播出去。下面讲述这一过程 点击“提交\"按钮时触发以下操作:

String city = ((EditText) findViewById(R.id.input)).getText().toString(); Intent intent = new Intent();

intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setClass(edit.this, CurrentWeather.class); Bundle mBundle = new Bundle();

mBundle.putString(\"Data\压入数据 intent.putExtras(mBundle); sendBroadcast(intent); finish();

如此CurrentWeather类便能获取到一个广播的Intent,从Intent的extras中提取城市名称并更新widget。 4.3.5 WeatherHandle类的实现 这个类的功能是使用sax解析xml 首先导入相关类:

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

继承DefaultHandler类,根据google api返回的xml数据格式进行解析。

- 31 -

3DII技术研究和应用实现

我主要重写了以下方法: startDocument() endDocument() startElement() endElement() charactors()

使用这些方法即可完成对xml文件的解析。

- 32 -

3DII技术研究和应用实现

第5章 相关实现技术与体会

本人是首次接触android系统与移动平台开发,在学习和开发的过程中遇到很多大大小小的问题,下面是我整理的典型问题和解决方案

5.1 添加widget

制作完widget之后要在Android模拟器中显示必须要手动添加自己制作的widget。

刚开始使用widget时由于不知道这一点,花费很长时间在检查代码上。 添加widget的过程如下所示: 点击Menu > add,出现以下图面

选择Widgets,在弹出来的对话中选择自己的应用

- 33 -

3DII技术研究和应用实现

5.2 RemoteViews的局限

App Widget的布局是基于RemoteViews的,RemoteViews主要有以下局限:

一、不支持findViewById()方法 二、只能使用有限的布局与控件 ·FrameLayout ·LinearLayout ·RelativeLayout

·AnalogClock ·Button ·Chronometer

- 34 -

3DII技术研究和应用实现

·ImageButton ·ImageView ·ProgressBar ·TextView

不支持这些类的派生。

一开始在我的设计中是想把文本输入框放在桌面的,但是由于RemoteViews不支持,所以会出现以下错误

于是只能修改设计,增加一个Activity。

5.3 在widget中显示图片

在还为做成widget前,软件可以使用网上的图片进行显示,但是做成widget后,RemoteViews不支持这种方式。RemoteViews有提供了一种方法可以实现图片显示,但是这种方法要先将图片导入程序res中。因为时间问题我没有在网上寻找icon的天气预报图标,所以在本次的widget设计中,没有显示天气的icon。

5.4 在AndroidManifest.xml中进行权限声明

AndroidManifest是一个相当重要的文件,相当于一个注册表,Activity,Broadcast,Service都要在这里进行注册。之前我使用CurrentWeather中的Service内部类没有忘记进行注册,导致Service没法启动,程序功能无法实

- 35 -

3DII技术研究和应用实现

现,为此花费我大量时间来检查代码。

权限声明在智能手机中是一种比较常见的应用程序保护机制,Android的基本思想是在AndroidManifest.xml文件中显示地声明应用程序需要的权限,防止应用程序错误地使用服务,不恰当地访问资源,最终达到提高Android应用程序的健壮性,改善用户体验的目的。 Android中的每种权限都用一个的标签表示,比如: Android.permission.SEND_SMS; Android.permission.CALL_PHONE;

从这些表示权限的名称中,不难发现其所代表的含义,如Android.permission.SEND_SMS表示发送短信的权限。

Android系统的每种功能或每种特性都用一个权限来表示,自然如果应用程序要访问某种特性就需要对权限进行声明。否则,应用程序将无法使用希望的功能,而且不会有缺少权限的错误提示!

5.5 为widget中的按钮设置Onclick事件

与普通的控件不同,RemoteViews没有OnClickListener方法,取而代之的是setOnClickPendingIntent方法---在点击RemoteViews对象时,用PendingIntent的方式来启动一个新的Activity,新的广播或新Service。 在我的设计中是这样实现的

Intent nIntent=new Intent(getApplicationContext(),edit.class);

PendingIntent pIntent=PendingIntent.getActivity(getApplicationContext()

,0,nIntent,0);

updateViews.setOnClickPendingIntent(R.id.btn,pIntent); 如此在点击按钮时即可发出Intent,启动新的Activity。

- 36 -

3DII技术研究和应用实现

5.6 利用Bundle实现消息的传递

由于要在Activity中将EditText的文本传递给AppWidgetProvider类,必须使用Intent的extras,利用Bundle的putString()方法,将信息压入Bundle,再使用Intent的putExtras()方法将Bundle放入Intent的extras中,具体实现如下例:

Intent intent=new Intent();

intent.setClass(TestBundle.this,Target.class); Bundle mbundle=new Bundle(); mBundle.putString(\"Data\ intent.putExtras(mBundle);

5.7 在AppWidgetProvider类中获取Intent的附加信息

刚开始实现CurrentWeather类时,只重载了onUpdate() 方法,但是这个方法的参数中没有Intent,而且在Broadcast类中无法使用getIntent()方法获取激活的Intent。

为了获得Intent的信息,我实现了Broadcast的onReceive()方法,通过此方法参数中的Intent获取激活自身的intent,再将intent的Action与AppWidgetManager.ACTION_APPWIDGET_UPDATE匹配,如果相同,则使用Bundle获取Intent中的Extras Bundle bundle=new bundle(); Bundle=intent.getExtras();

再使用Bundle的getString方法获取文本信息。 最后在onReceive()方法中启动更新服务。

- 37 -

3DII技术研究和应用实现

5.8 软件使用

首先根据以上添加widget的方法,添加应用CurrentWeather 在android模拟器的桌面可以看到以下widget

guangzhou,china是用户选择的城市中国广州,右边的按钮用于修改要进行天气预报的城市。

Haze是天气状况,表示是雾天气,下面的两行分别显示当天广州的温度和湿度。

- 38 -

3DII技术研究和应用实现

点击“改变城市”按钮,弹出以下画面:

在本输入框输入城市,点击提交,即可更换城市,并关闭本页面,回到桌面,如下所示:

- 39 -

3DII技术研究和应用实现

- 40 -

3DII技术研究和应用实现

结论

本文首先对android系统做了一个简单介绍,随后介绍Android开发环境的搭建,然后就Android开发基础知识进行讲解,对Android应用程序结构和基本组件进行介绍。接着切入到软件的设计与实现上,最后描述了学习和开发过程中所遇到的问题以及相应的解决方案。

本文主旨在于说明Android开发的流程,通过实现软件的网络功能与widget制作,熟悉了Android开发的基本思想与流程,熟悉Android程序中的各个组件以及组件之间联系的实现。

在软件的设计与实现过程中,我遇到不少的问题,从刚开始熟悉Android的各个组件到Intent的传值问题,到后面设计网络部分查找了相关的类,随后在widget的实现中由于RemoteViews的局限性产生的严重问题,导致程序无法正常运行。

现在软件的基本功能已经完善,能在桌面安装,按时更新天气预报信息而且可以自己选择需要的城市进行天气预报。 但是软件也存在许多可以改进的地方,如下: (1)更为华丽的外观

(2)加入天气icon,是天气预报看起来更加直观

(3)布局上的改善,按钮显得有些突兀,可以使用制作图片按钮 由于本人水平有限,文中如有不足之处,敬请指正。

- 41 -

3DII技术研究和应用实现

致谢

感谢我的导师孟小华老师,谢谢他对我的悉心指导,这段时间老师给予了我许多无私的关怀和帮助,他严谨的治学态度以及有的放矢的指导方法给了我很大的激励,帮我开拓了思路,并将使我终生受益。在此向孟小华老师致以诚挚的谢意和崇高的敬意。

其次,还要感谢大学期间为我传授知识的老师们,感谢他们给了我宝贵的知识,使我成长。

- 42 -

3DII技术研究和应用实现

参考文献

[1] Ed Burnette 著Android基础教程 . 张波,高朝勤,杨越 译. 北京:人民邮电出版社,2009 40-69

[2]靳岩,姚尚朗 著Android开发入门与实战. 北京:人民邮电出版社, 2009 8-16

[3]E2ECloud工作室 著 深入浅出 Google Android 北京:人民邮电出版社, 2009 237-256

[4]Android SDK 1.6开发帮助文档

android-sdk-windows-1.6_r1/docs/guide/topics/appwidgets/index.html [5]Android SDK 1.6 开发帮助文档

android-sdk-windows-1.6_r1/docs/guide/topics/fundamentals.html [6]Android SDK 1.6 开发帮助文档

android-sdk-windows-1.6_r1/docs/reference/android/content/Intent.html [7]Android SDK 1.6 开发帮助文档

android-sdk-windows-1.6_r1/docs/reference/android/content/ BroadcastReceiver.html

- 43 -

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- dfix.cn 版权所有 湘ICP备2024080961号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务