[毕业论文]基于安卓的图片浏览器的设计与实现

发布时间:2015-03-18 10:10:43   来源:文档文库   
字号:

Android一词的本义指“机器人”,同时也是Google2007115日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。目前,最新版本为Android 4.0 Ice Cream Sandwich

Android早期由原名为"Android"的公司开发,谷歌在2005年收购"Android.Inc"后,继续对Android系统开发运营,它采用了软件堆层(software stack,又名软件叠层)的架构,主要分为三部分。底层以Linux内核工作为基础,由C语言开发,只提供基本功能;中间层包括函数库Library和虚拟机Virtual Machine,由C++开发。最上层是各种应用软件,包括通话程序,短信程序等,应用软件则由各公司自行开发,以Java作为编写程序的一部分。Android 作为Google企业战略的重要组成部分,将进一步推进“随时随地为每个人提供信息”这一企业目标的实现。全球为数众多的移动电话用户正在使用各种基于 Android 的电话。谷歌的目标是让(移动通讯)不依赖于设备甚至平台。出于这个目的,Android 将补充,而不会替代谷歌长期以来奉行的移动发展战略:通过与全球各地的手机制造商和移动运营商结成合作伙伴,开发既有用又有吸引力的移动服务,并推广这些产品。  

2011年初数据显示,仅正式上市两年的操作系统Android已经超越称霸十年的塞班系统,使之跃居全球最受欢迎的智能手机平台。Android的主要竞争对手是苹果公司的iOS以及RIMBlackberry OS[2]

【关键词】Android Linux平台 开源手机操作系统 移动软件 Google



ABSTRACT

The word “Android” means a robot. It is also the name of the open-Source operating system for mobile phone which is based on Linux and presented by Google November 5th of 2007. This system platform is made up with operating system, middleware, UI and applications. It is known as the first real Open Source and integrated software for Mobile Terminal. At present the latest version of the system is Android 4.0 Ice Cream Sandwich.

Android operating system is based on the open-core of Linux. This system is developed by a company named “Android” at early stage. After Google buy “Android.Inc”, Google go on developing and managing Android operating system. This operating system uses the software-stack framework. It is mainly divided into 3 parts. Basement Linux-core only provides basic function. This part is coded by C. Interlayer which is coding by C++ includes Function Library and Virtual Machine. The superstratum is made up with various kinds of applications including communication procedures, message procedures and so on. These applications are developed by other companies themselves. Some of them are coding by java. Android as the significant part of Google`s business strategy will move forward a single step to advance the business goal called “providing information for everybody anytime and anywhere”. Large numbers of people all over the world are using mobile phone which is based on Android. Google`s purpose is to let the mobile communication do not depend on the equipments even if the platform. For this purpose, Android will complement, not replace Google has long pursued a strategy of mobile development: partnership, the development of useful, attractive mobile services through the mobile phone manufacturers and mobile operators around the globe, and promotion of these products.

The data show that early 2011 officially listed only two years of operating system Android has surpassed dominate the decade of the Symbian system, making it the largest in the world's most popular smart phone platform. Android's main competitor is the Apple IOS and RIM of the Blackberry OS.

Key wordsAndroid Linux platform open-source-operating-system-for-mobile-phone mobile software Google





以往的手机图片浏览器,通常是使用键盘键,即上下左右按钮实现不同图片的切换,操作上很不友好。而且现如今移动通信技术日新月异,各类触屏手机层数不穷,用户需求渐渐变高,以往的操作方式已经不能满足用户对应用的要求。不仅仅在实用性上,还包括简单、快捷、人性化的操作。所以开发一款针对触屏的手机的图片浏览器是很有必要的。

本文主要阐述以面向对象的程序开发语言JAVAeclipse作为开发集成环境,基于智能手机Android操作系统之上设计一个图片浏览器。该图片浏览器主要实现本地图片(存储在SD卡上的图片)的浏览,并能查看浏览历史。借助Android系统的全触摸的形式,增强用户的体验。用户可以用简单、快捷、人性化的操作浏览图片。



第一章 基于安卓的图片浏览器概述

第一节 研究内容

Android是基于Linux内核的软件平台和操作系统,早期由Google开发,后由开放手机联盟Open Handset Alliance)开发。它采用了软件堆层(software stack,又名以软件叠层)的架构,主要分为三部分。低层以Linux内核工作为基础,只提供基本功能;其他的应用软件则由各公司自行开发,以Java作为编写程序的一部分。另外,为了推广此技术,Google和其它几十个手机公司建立了开放手机联盟[1]

Android平台图片浏览器是基于Android手机平台,运用JAVA语言和Android SDK,开发针对Android平台的图片浏览器。

第二节 研究意义

借助Android系统的全触摸的形式,用户可以用手指简单的滑动、点击浏览本地图片,并记录用户浏览历史,方便用户查看以前浏览过的图片和图片地址,从而增强用户体验和易用性。

第三节 研究现状和发展趋势

Android系统于2007年在美国推出后, Android凭借其良好的用户体验,低廉的成本和较高的开放性吸引着越来越多的终端厂商采用,根据Gartner等国际研究机构的报告,Android2010年第3季度全球智能手机市场的份额已达25.5%,而在去年同期Android市场份额只有3.5%

  Android出现之前,智能手机OS市场中SymbianWM两者占据大部分市场份额,但在移动互联网的快速发展,终端+应用的趋势逐渐成为主流的情况下,两者的劣势逐渐突出。Symbian由于发展多年,底层架构较为陈旧且对触摸屏支持不佳,用户体验较差;再加上系统较为封闭,支持的应用较少。WM系统同样较为封闭,对终端厂商来讲引入成本较为昂贵,娱乐性平平,多用于商务机型。

  2007年,苹果iPhone上市后iOS凭借iPhone优秀的用户体验和App Store在线商店模式获得了巨大的成功,特别值得一提的是App Store应用开发分成模式刺激了开发者不断进入,截至20108月,可用于iOS的应用已超25万,苹果公司顺应了终端+应用的智能手机发展趋势,取得了快速的发展.iOS也遇到许多问题, iOS属于半开放的OS,实现移动互联网产业链上各环节的普赢还是较为困难;其次iPhone定价较高,短期内难以满足中低端市场的需求。

  反观Android系统,拥有低廉的引入成本,良好的用户体验开放性较强的特点,加上Android Market和众多第三方应用商店做后盾,在应用方面的资源也非常丰富;虽然Android目前存在安全性和版本混乱等问题,但由于其适应了移动互联网的发展趋势,切合了移动互联网产业链各方的发展变化需求,所以取得了迅猛的发展。

  移动互联网的蓬勃发展促使手机终端产业链变化,应用和服务逐渐成为竞争的焦点。无论是电信运营商,终端厂商还是应用开发商,目前都在向操作系统领域进军,试图对内容的聚拢和对应用体系的把控,稳固或加强自己在产业链中的影响力。在这一过程中Android系统因多方面因素逐渐受到各方的青睐。

  电信运管商方面,通过产业链优势(销售渠道优势、用户优势、资源整合优势)向操作系统领域进行扩张,达到控制更多产业链话语权的目的是现阶段移动互联网发展的必然趋势。相对于其他系统Android的开放性和可定制性使得运营商从系统层面打造自己的用户界面,并内置增值服务更加容易。中国移动专门为定制了基于AndroidOPhone平台,并与索爱,三星及摩托罗拉等厂商联合推出了多款OPhone终端;联通方面uPhone也呼之欲出。运营商的这一举动,不仅加强了其产业链上的话语权,同时也会极有利于Android系统手机向中低端大众市场推广[12]



第二章 开发环境概述

第一节 开发平台

本应用软件基于Android开源移动平台开发,借助其SDK(软件开发程序包)和强大的全触摸的形式,实现图片浏览的功能。使用面向对象语言JAVA开发。由于Android开发集成在Eclipse中,所以选择Eclipse作为集成开发环境。采用Eclipse 集成的ADT(虚拟机)进行调试和运行。

第二节 Android框架简介

1.2 Android系统结构图

一、Applications(应用层)

应用是用Java语言编写的云新在虚拟机上的程序。

二、Application Framework(应用框架层)

这一层是编写Google发布的核心应用时所使用的API框架,开发人员可以使用这些框架来开发自己的应用。

View System:可以用来构建应用程序,它包括列表、网格、文本框、按钮以及可嵌入的Web浏览器。

Content Providers:它可以让一个应用访问另一个应用的数据,或共享它们自己的数据。

Resource Manager:提供非代码资源的访问,如本地字符串、图形和布局文件。

Notification Manager:应用可以在状态栏中显示自定义的提示信息。

Activity Manager:用来管理应用程序生命周期并提供常用的导航退回功能。

Window Manager:管理所有的窗口程序。

Package ManagerAndroid系统内的程序管理。

三、LibrariesAndroid Runtime(系统运行库层)

当使用Android应用框架时,Android系统会通过一些C/C++库赖支持我们使用的各个组件,使其能更好地为我们服务。

  Bionic系统C库:C语言标准库,系统最底层的的库,C库通过Linux系统来调用。

  多媒体库(MediaFramework):Android系统多媒体库,基于PackerVideo OpenCORE,该库支持多种常见格式的音频、视频的回放和录制,以及图片,比如MPEG4MP3AACAMRJPGPNG等。

  SGL2D图形引擎库。

  SSL:位于TCP/IP协议与各种应用层协议之间,为数据通信提供支持。

  OpenGL ES 1.03D效果的支持。

  SQLite:关系数据库。

  WebkitWeb浏览器引擎。

  FreeType:位图(bitmap)及矢量(vector)。

  在Android操作系统中,每个Java程序都运行在Dalvik虚拟机上,其只能执行.dex的可执行文件,当Java程序通过编译后,最后还需要通过SDK中的dx工具转为成.dex格式才能正常在虚拟机上执行,Java虚拟机运行的是Java字节码,而Dalvik虚拟机运行的则是其专有的文件格式dexDalvik Exceutable)的文件。

  Dalvik虚拟机有如下几个主要特征:

  1.专有的dex文件格式。

  2.dex的优化,dex文件的结构是紧凑的。

  3.基于寄存器。

4.一个应用,一个虚拟机实例,一个进程。每一个Android应用度运行在一个Dalvik虚拟机实例中,每一个虚拟机实例都是一个独立的进程空间。

四、Linux KernelLinux内核层)

  显示驱动(Display Driver):基于Linux的帧缓冲(Frame Buffer)驱动。

  键盘驱动(KeyBoard Driver):作为输入设备的键盘驱动。

  Flash内存驱动(Flase Memory Driver):基于MTDFlash驱动程序。

  照相机驱动(Camera Driver):常用的基于Linuxv412Video for Linux)的驱动。

  音频驱动(Audio Driver):常用的基于ALSA的高级Linux声音体系驱动。

  蓝牙驱动(Bluetooth Driver):基于IEEE 802.15.1标准的无线传输技术。

  WiFi驱动:基于IEEE 802.11标准的驱动程序。

  Binder IPC驱动:Android的一个特殊的驱动程序,具有单独的设备节点,提供进程间通信的功能。

Power Management(电源管理):比如电池电量等。

五、Android应用程序框架

  android.app:提供高层的程序模型和基本的运行环境。

  android.content:包含对各种设备上的数据进行访问和发布。

  android.database:通过内容提供者浏览和操作数据库。

  android.graphics:底层的图形库,包含画布i、颜色过滤、点、矩形,可以将它们直接绘制到屏幕上。

  android.location:定位和相关服务的类。

  android.media:提供一些类管理多种音频、视频的媒体接口。

  android.net:提供帮助网络访问的类,超过通常的java.net.*接口。

  android.os:提供了系统服务、消息传输和IPC机制。

  android.opengl:提供OpenGL的工具。

  android.provider:提供访问Android内容提供者的类。

  android.telephony:提供与拨打电话相关的API交互。

  android.view:提供基础的用户界面接口框架。

  android.util:涉及工具性的方法,例如时间日期的操作。

  android.webkit:默认浏览器操作接口。

  android.widget:包含各种UI元素在应用程序的布局中使用[11]



第三章 系统分析

第一节 研究目标

1) 了解Android应用成熟的设计和开发过程;

2) 熟悉Android内置SDK

3) 使用多种组件实现Android平台图片浏览器开发;

第二节 需求分析

本应用软件是一个AppWidget应用程序,启动后自动搜索SDCARD上的本地图片并显示在主界面。用户通过滑动屏幕实现不同图片的切换和浏览,并可以设置图片为主屏幕的壁纸。用户已经浏览过的图片记录进浏览历史。

浏览历史包括图片的名称、图片的存储路径以及用户浏览该图片的时间。用户可以通过浏览历史查看以前浏览过的图片,并可以清空浏览记录。

1) 启动AppWidget应用程序;

2) 浏览图片:滑动底部缩略图,并点击图片后,在中部展示图片;

3) 设置壁纸:将选中的图片设置为主屏幕壁纸;

4) 查看浏览历史:查看用户已经浏览过的图片;

5) 清空浏览历史:清空用户的浏览历史。

第三节 平台搭建

一、安装JDK

http://www.oracle.com/technetwork/java/javase/downloads/index.html 下载 JDK 6 Update 20

: 根据www.eclipse.org的官方信息,在windows 平台上安装了JDK 6 Update 21,然后运行Eclipse Helios (3.6) 会出现 crashing,需要进行一些设置 ( http://wiki.eclipse.org/FAQ_How_do_I_run_Eclipse%3F#Oracle.2FSun_VM_1.6.0_21_on_Windows )

1) 双击 jdk-6u20-windows-i586.exe 进行安装

2) 安装完成后,在命令行中输入 "java -version",若出现以下信息则表示安装成功:

java version "1.6.0_20"

Java(TM) SE Runtime Environment (build 1.6.0_20-b02)

Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

二、安装Android SDK

通过查询资料得知,googleAndroid官方网址已经由 http://dl.google.com/android 迁移到了 http://developer.android.com,但是遗憾的是国内对网站 developer.android.com 进行了屏蔽,无法直接访问。

大家可以通过代理软件或在线代理来访问(速度稍慢),也可以访问developer.android.com的镜像。下面是整理的几个镜像网址:

http://androidappdocs.appspot.com

https://txt.appspot.com/developer.android.com

这里使用 androidappdocs.appspot.com 这个镜像网站来访问 developer.android.com

选择SDK这个tab项,发现现在最新的Android SDK版本是2.2

1) 下载 android-sdk_r06-windows.zip,大小是 23293160 bytes MD5 7c7fcec3c6b5c7c3df6ae654b27effb5

2) 解压 android-sdk_r06-windows.zip 到你想安装Android SDK的目录。这里解压到D:\,于是生成了D:\android-sdk-windows\这个目录。

3) 在环境变量中的PATH中加D:\android-sdk-windows\tools

4) 由于google改变了下载策略(以前是sdk所以的文件集成在一个安装包中,可以离线安装),现在必须在线实时地从google网站上下载需要安装的文件来进行在线安装。双击 D:\android-sdk-windows\SDK Setup.exe 运行 Android SDK and AVD Manager一般情况下都出现下面的提示: Failed to fetch URL http://dl-ssl.google.com/android/repository/repository.xml, reason: Connection timed out: connect

  我们需要关闭 "Refresh Sources" "Choose Packages to Install"窗口,点击选中左侧栏目中的 "Settings" "Force https//... sources to be " 勾选上,然后再选中左侧栏目中的 "Available Packages" 条目,点击 Refresh,应该就可以成功获取到安装列表了。

5) 在安装列表中选择要安装的 apis 版本、usb驱动、SDK例子程序和SDK文档等。安装的是 Android 2.2 SDK,对应的API代号是8

三、创建一个新的 Android Virtual Device (AVD)

新建AVD时的 emulate 设置

1) “Android SDK and AVD Manager”窗口的左侧选择 “Virtual Devices”

  i.选择 “New”

ii.输入一个AVD Name

iii.选择一个 Target 

iv.输入模拟的 SD Card 的容量大小 

v.选择一个外观皮肤 Skin     

保留默认的skin设置值让模拟器外观大小像 G1, MyTouch 3G, Hero, 等手机设备

选择 WVGA 854

* 模拟 Motorola Droid

选择列表内其他的选项

* 模拟其他的设备

vi.然后 “Create AVD”,如图3.3.1所示

图表 3.3.1 Create new AVD

 

在列表里选择新建的要运行的模拟器(Virtual Device)如图3.3.2所示

3.3.2 模拟器选择框

 

 单击 "Start..."后弹出如下提示框:

3.3.3 点击Start弹出框

 

单击 "Launch"按钮开始运行模拟器。

3.3.4 模拟器运行图

 

首次运行需要几分钟的时间

3.3.5 运行成功

 

 

四、 安装 Eclipse

这里安装的是 Eclipse IDE for Java Developers (Eclipse Helios, 3.6)。下载完成之后,直接解压即可(的安装路径 C:\Program Files\eclipse_java )

 

安装 EclipseAndroid ADT插件

1) 可以直接到Android官网去下载这个ADT插件。到 http://androidappdocs.appspot.com/sdk/eclipse-adt.html#installing 这里下载了ADT-0.9.7.zip,大小是 8033750 bytes 接着安装ADT插件,这里是使用的直接拷贝的方式来安装的,大家也可以通过links方式安装。

  2) 在这一步也可以通过Eclipse自身的update功能进行下载:启动Eclipse,选择【Help > Soft Updates > Find and Install… (或者是 Help > Soft Updates, in the dialog that appears, click the Available Software tab )

In the "Location" field, enter this URL:https://dl-ssl.google.com/android/eclipse/

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

  If Eclipse can not find the remote update site containing the ADT plugin, try changing the remote site URL to use http, rather than https. That is, set the Location for the remote site to: http://dl-ssl.google.com/android/eclipse/

  注:许多国内的网友都无法完成这样的升级,通常是进行到一半就没有任何反映了(其他插件,例如pydev也是这样)。

 六、 配置 Eclipse Android ADT插件

1) 设置EclipseJava JDK属性设置    选择【Window>Preferences…】打开编辑属性窗口;选择Java属性 面板;选择Java编译器为6.0;点击Apply,和OK

2) 进行Android SDK设置    选择【Windows > Preferences…】打开编辑属性窗口;选择Android属性面板;加入Android SDK的目录(点击【Browse…】进行选择,这里是 "D:\android-sdk-windows\" 目录)。

七、 测试开发环境

 搭建好开发环境之后,我们来创建一个Hello World工程,体验一下Android的开发。     1) 选择【File>New>Project     2) 选择【Android>Android Project】,点击【Next

3.3.6 新建项目

 

   

3) 对新工程进行设置,点击 Finish

3.3.7 新工程设置

运行程序,第一次启动AVD,时间有点长,运行效果为

3.3.8 项目运行效果



第四章 程序设计

第一节 用户界面设计

根据需求分析可以知道,应用程序应该包含3个主要的界面:浏览图片界面、查看浏览历史界面、查看历史图片界面。这里需要进一步分析每个界面显示的内容。

在浏览图片界面中,需要2个区域,一个显示缩略图,另一个显示图片。为了界面不显得拥挤,把设置壁纸和查看浏览历史按钮放在MENU按钮中。浏览历史界面采用列表的形式展现,用户通过滑动屏幕查看浏览历史,点击具体的一项跳转历史图片查看界面。在历史图片查看界面展示选中的浏览历史指向的图片。

根据用户界面显示内容分析,绘制出用户界面,如下图所示

4.1. 界面

第二节 存储设计

本应用软件读取的图片来自于用户的手机存储卡,存储的历史记录信息单一简单,故不采用AndroidSQLite数据库,用xml文件来存储用户的浏览历史。Xml文件存储在SDCARD中。根据需求分析,把浏览历史文件命名为History.xmlHistory.xml文件设计结构如下:

图片名称

图片路径

访问日期

第三节 程序模块设计

功能需求上分析可以看出,整个应用程序划分为3个模块:浏览图片、浏览历史、浏览历史图片和读取、清空xml文件。各个模块之间的关系如下图

4.3 模块划分

从图中不难看出,后台处理是程序的核心,PictureBowserActivity负责读取SDCARD中的图片,并始化图片浏览页面控件;HistoryActivity负责读取浏览历史文件History.xml,初始化浏览历史页面控件, 并发送参数到ViewActivityViewActivity负责接受从HistoryActivity传来的参数,从SDCARD中读取图片初始化历史图片浏览页面控件。



第五章 程序开发

第一节 文件结构与用途

在程序开发阶段,首先确定基于Android的图片浏览器的工程名为PictureBrowserPictureBrowser源码结构如下图所示:

5.1 源码结构

为了使源代码文件结构更加清晰,PictureBrowser工程设置了多个命名空间,分别用来存放后台Activity、浏览历史bean以及工具类。源码文件的名称及说明如下表所示:

5.1.1 源码名称作用表

包名称

文件名

说明

pic.beans

History.java

浏览历史bean

pic.PictureBrowser

HistoryActivity.java

浏览历史后台Activity

pic.PictureBrowser

PictureBrowserActivity.java

图片浏览后台Activity

pic.PictureBrowser

ViewActivity.java

浏览历史图片后台Activity

pic.utils

HistoryOperate.java

操作浏览历史文件的工具类,提供xml的创建

、修改等

Android的资源文件保存在/res的子目录中。其中/res/layout目录中保存的是页面XML文件,具体用途如下表所示:

5.1.2 资源文件名称与用途表

资源目录

文件名

说明

layout

main.xml

浏览图片页面

history.xml

浏览历史页面

view.xml

浏览历史图片页面

第二节 核心代码

一、Xml文件操作

由于本应用需要操作XML文件,所以需要bean类和XML文件操作类。Bean类具体代码如下:

History.java

package pic.beans;

/*浏览历史bean*/

public class History {

private String name;//文件名

private String path;//文件路径

private String date;//浏览时间

public History(String name,String path,String date){

this.name = name;

this.path = path;

this.date = date;

}

public String getDate(){

return date;

}

public void setDate(String date){

this.date = date;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getPath() {

return path;

}

public void setPath(String path) {

this.path = path;

}

public History(){

}

}

XML文件操作类代码如下

HistoryOperate.java

public class HistoryOprate {

/*创建历史记录xml*/

public static void createXml(){

File xmlFile = new File(Environment.getExternalStorageDirectory()+File.separator+"history.xml");

try {

FileOutputStream fos = new FileOutputStream(xmlFile);

xmlFile.createNewFile();

byte[] header = new byte[512];

String headerText = "";

header = headerText.getBytes();

fos.write(header);

fos.flush();

fos.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

/*写入浏览记录*/

public static void writeXml(History history){

/*DOM操作XML*/

String xmlPath = Environment.getExternalStorageDirectory()+File.separator+"history.xml";

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {

DocumentBuilder builder = factory.newDocumentBuilder();

Document doc = builder.parse(new File(xmlPath));

doc.normalize();

Node father = doc.getElementsByTagName("histories").item(0);

Node child = doc.createElement("history");

Node name = doc.createElement("name");

Text nameText = doc.createTextNode(history.getName());

name.appendChild(nameText);

Node path = doc.createElement("path");

Text pathName = doc.createTextNode(history.getPath());

path.appendChild(pathName);

Node date = doc.createElement("date");

Text dateName = doc.createTextNode(history.getDate());

date.appendChild(dateName);

child.appendChild(name);

child.appendChild(path);

child.appendChild(date);

father.appendChild(child);

TransformerFactory tfactory = TransformerFactory.newInstance();

Transformer transformer = tfactory.newTransformer();

DOMSource source = new DOMSource(doc);

StreamResult result = new StreamResult(xmlPath);

transformer.transform(source, result);

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (TransformerConfigurationException e) {

e.printStackTrace();

} catch (TransformerException e) {

e.printStackTrace();

}

}

/*获取历史记录*/

public static List readXml(InputStream in){

List histories= null;

History history = null;

XmlPullParser parser = Xml.newPullParser();

try {

parser.setInput(in,"UTF-8");

int eventCode = parser.getEventType();

while(eventCode!=XmlPullParser.END_DOCUMENT){

switch (eventCode) {

case XmlPullParser.START_TAG: //当读取到的是开始标签,new一个History对象,对其赋值

if("history".equals(parser.getName())){

history = new History();

}else if("name".equals(parser.getName())){

if(history!=null){

history.setName(new String(parser.nextText()));

}

}else if("path".equals(parser.getName())){

if(history!=null){

history.setPath(new String(parser.nextText()));

}

}else if("date".equals(parser.getName())){

if(history!=null){

history.setDate(new String(parser.nextText()));

}

}

break;

case XmlPullParser.END_TAG: //当读到的是结束标签,将History对象加入List列表

if("history".equals(parser.getName())&&history!=null){

histories.add(history);

history = null;

}

break;

case XmlPullParser.START_DOCUMENT: //当读取到的是文件头

histories = new List();

break;

}

eventCode = parser.next();

}

return histories;

} catch (Exception e) {

return null;

}finally{

try {

in.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

二、 页面布局xml

本应用一共有3个页面,main.xml(浏览图片页面)、history.xml(浏览历史页面)、view.xml(历史图片浏览页面)。由于浏览历史页面和历史图片浏览页面布局与浏览图片页面较为重复,所以这里就只将浏览图片页面和历史记录页面代码贴出。

main.xml页面,采用了ImageSwitcher+Gallery组件框架设计,其布局代码如下:

main.xml

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_gravity="top"

android:orientation="vertical" >

android:id="@+id/imageswitcher"

android:layout_width="match_parent"

android:layout_height="400dp"

android:layout_gravity="top|left"

android:orientation="vertical"/>

android:id="@+id/gallery"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_gravity="bottom|left"

android:background="#55000000"

android:orientation="vertical"/>

浏览历史界面采用的是ListActivity控件,其中的getView()方法获取如下history.xml的布局:

history.xml

android:orientation="vertical"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textColor="#FFFFFFFF"

android:textSize="15dp" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textColor="#808080"

android:textSize="13dp" />

三、 后台 Activity

图片浏览页面采用的ImageSwitcher+Gallery布局,后台Activity中需要注册这2个控件。

ImageSwicher的注册,工厂设置

/*获取ImageSwitcher控件,设置工厂并设置动画效果*/

is = (ImageSwitcher) findViewById(R.id.imageswitcher);

is.setFactory(this);

is.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));

is.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));

is.setImageResource(R.drawable.null_is);

Gallery的注册,绑定自定义适配器:

/*获取Gallery控件,设置ImageAdapter,添加OnItemClick事件监听*/

gallery = (Gallery) findViewById(R.id.gallery);

ImageAdapter ia = new ImageAdapter(this);

gallery.setAdapter(ia);

gallery.setOnItemClickListener(this);

gallery.setSelection(1);//设置默认选中的图片

自定义适配器:

/*ImageAdapter*/

public class ImageAdapter extends BaseAdapter{

private Context context;

int mGalleryItemBackground ;

public ImageAdapter(Context c){

context = c;

Typed ta = obtainStyledAttributes(R.styleable.Gallery);

mGalleryItemBackground = ta.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0);

}

@Override

public int getCount() {

return Integer.MAX_VALUE;//传入一个很大的值以实现循环滑动

}

@Override

public Object getItem(int position) {

return position;

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View arg1, ViewGroup arg2) {

ImageView i = new ImageView(context);

/*images文件夹下无图片时调用*/

if(pic_res.isEmpty()){

i.setImageResource(R.drawable.null_ga);

return i;

}

/*images文件夹下有图片时调用*/

else{

i.setImageURI(pic_res.get(position%pic_res.size()));

i.setAdjustViewBounds(true);

i.setLayoutParams(new Gallery.LayoutParams(

LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));

i.setBackgroundResource(mGalleryItemBackground);

return i;

}

}

}

浏览历史Activity采用继承ListActivity,这个Activity重写了onListItemClick(ListView l, View v, int position, long id)方法,并绑定了自定义适配器,核心代码如下:

/*自定义Adapter*/

public class MyAdapter extends BaseAdapter{

private LayoutInflater mInflater;

public MyAdapter(Context context){

this.mInflater = LayoutInflater.from(context);

}

@Override

public int getCount() {

return mData.size();

}

@Override

public Object getItem(int arg0) {

return null;

}

@Override

public long getItemId(int arg0) {

return 0;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder = null;

if (convertView == null) {

holder=new ViewHolder();

convertView = mInflater.inflate(R.layout.history, null);

holder.title = (TextView)convertView.findViewById(R.id.title);

holder.info = (TextView)convertView.findViewById(R.id.info);

convertView.setTag(holder);

}else {

holder = (ViewHolder)convertView.getTag();

}

holder.title.setText((String)mData.get(position).get("title"));

holder.info.setText((String)mData.get(position).get("info"));

return convertView;

}

}

历史图片浏览页面采用TextView布局,图片放在文本上方,其代码如下:

private TextView textView;

@Override

protected void onCreate(Bundle savedInstanceState) {

setContentView(R.layout.view);

textView = (TextView) findViewById(R.id.textView);

Intent intent = this.getIntent(); //接收参数

Bundle bundle = intent.getExtras();

String path = bundle.getString("path");

Bitmap bitmap = BitmapFactory.decodeFile(path);

Drawable dra = new BitmapDrawable(bitmap); //获取图片drawable

dra.setBounds(0, 0, 700, 680); //设置图片在位置、大小

textView.setCompoundDrawables(null, dra, null, null); //在返回按钮上方显示图片

textView.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

Intent i = new Intent();

i.setClass(ViewActivity.this,HistoryActivity.class);

startActivity(i);

ViewActivity.this.finish();//返回浏览历史

}

});

super.onCreate(savedInstanceState);

}

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK) {//拦截返回按钮事件

Intent intent = new Intent();

intent.setClass(ViewActivity.this,HistoryActivity.class);

startActivity(intent);

ViewActivity.this.finish();

}

return super.onKeyDown(keyCode, event);

}

在设计开发过程中,遇到了很多问题和困难,在解决过程中获益非浅,特别是如何分析、建立、开发一个系统方面,有以下结论或体会:

在一个系统开发的过程中编码不是最重要的,重要的是系统的需求分析、如何建立系统模型。

而且一个成功的软件要符合用户的需要,要以用户为中心,开发出用户想要的软件,而不能自以为是想当然。

在程序编写中,我认识到软件要有简洁便利的界面,良好的程序风格,完备的文挡。拥有这些条件,程序的可读性才会好,开发的复杂度才能大大减少,修改代码时更加容易、更加方便。

要养成良好的编程风格与习惯:包括程序的模块化、必要的注释和完备的设计文挡三个方面。

软件的不足有以下几点:代码的健壮性还很差,用户操作界面还不够灵活,功能也不完善,这些问题还需要今后逐一解决。



参考文献

[1] 姚尚郎.Google Android 开发入门与实战.人民邮电出版社

[2] 景保玉.2012中国移动应用开发闲置与趋势大调查.20110112

[3] Michael JYoung.轻松搞定XML 林嘉胜译.3[P]20010108

[4] (英)Herbert Scheldt Java参考大全.清华大学出版社

[5] 王向辉,张国印,沈洁.Android应用程序开发.清华大学出版社,20123

[6] 搭建Android 2.2 开发环境 http://www.cnblogs.com/cheney23reg/archive/

2010/08/19/1803474.html

[7] Android中文API合集(83篇)Android 中文翻译组

[8] 杨丰盛Android应用开发揭秘机械工业出版社

[9] 余志龙(作者) 王世江(改编)Google Android SDK 开发范例大全(第二版)人民邮电出版社

[10] Android手把手开发一个图片浏览器百度文库

[11] 胡伟Android系统架构及其驱动研究[J] 广州广播电视大学学报

[12] 郑健 贺超AndroidChrome的发展与未来移动通信2010.3

[13] Frank Ableson Introduction to Android development [EB/OL]

http://www.ibm.com/developerworks/opensource/library/os-android-devel/index.html

[14] 刘昌平 范明钰Android手机的轻量级访问控制[J] 计算机应用研究2010,7

[15] 张运芳Android创赢路线与产品开发实战[M] 北京:北京工业出版社2010

源程序:

浏览历史操作类:HistoryOprate.java

public class HistoryOprate {

/*创建历史记录xml*/

public static void createXml(){

File xmlFile = new File(Environment.getExternalStorageDirectory()+File.separator+"history.xml");

try {

FileOutputStream fos = new FileOutputStream(xmlFile);

xmlFile.createNewFile();

byte[] header = new byte[512];

String headerText = "";

header = headerText.getBytes();

fos.write(header);

fos.flush();

fos.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

/*写入浏览记录*/

public static void writeXml(History history){

/*DOM操作XML*/

String xmlPath = Environment.getExternalStorageDirectory()+File.separator+"history.xml";

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {

DocumentBuilder builder = factory.newDocumentBuilder();

Document doc = builder.parse(new File(xmlPath));

doc.normalize();

Node father = doc.getElementsByTagName("histories").item(0);

Node child = doc.createElement("history");

Node name = doc.createElement("name");

Text nameText = doc.createTextNode(history.getName());

name.appendChild(nameText);

Node path = doc.createElement("path");

Text pathName = doc.createTextNode(history.getPath());

path.appendChild(pathName);

Node date = doc.createElement("date");

Text dateName = doc.createTextNode(history.getDate());

date.appendChild(dateName);

child.appendChild(name);

child.appendChild(path);

child.appendChild(date);

father.appendChild(child);

TransformerFactory tfactory = TransformerFactory.newInstance();

Transformer transformer = tfactory.newTransformer();

DOMSource source = new DOMSource(doc);

StreamResult result = new StreamResult(xmlPath);

transformer.transform(source, result);

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (TransformerConfigurationException e) {

e.printStackTrace();

} catch (TransformerException e) {

e.printStackTrace();

}

}

/*获取历史记录*/

public static List readXml(InputStream in){

List histories= null;

History history = null;

XmlPullParser parser = Xml.newPullParser();

try {

parser.setInput(in,"UTF-8");

int eventCode = parser.getEventType();

while(eventCode!=XmlPullParser.END_DOCUMENT){

switch (eventCode) {

case XmlPullParser.START_TAG: //当读取到的是开始标签,new一个History对象,对其赋值

if("history".equals(parser.getName())){

history = new History();

}else if("name".equals(parser.getName())){

if(history!=null){

history.setName(new String(parser.nextText()));

}

}else if("path".equals(parser.getName())){

if(history!=null){

history.setPath(new String(parser.nextText()));

}

}else if("date".equals(parser.getName())){

if(history!=null){

history.setDate(new String(parser.nextText()));

}

}

break;

case XmlPullParser.END_TAG: //当读到的是结束标签,将History对象加入List列表

if("history".equals(parser.getName())&&history!=null){

histories.add(history);

history = null;

}

break;

case XmlPullParser.START_DOCUMENT: //当读取到的是文件头

histories = new List();

break;

}

eventCode = parser.next();

}

return histories;

} catch (Exception e) {

return null;

}finally{

try {

in.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

History.java中设置menu按钮

/*设置menu菜单*/

@Override

public boolean onCreateOptionsMenu(Menu menu) {

menu.add(0,1,0,"清空历史记录");

menu.add(0,2,0,"返回浏览器");

return super.onCreateOptionsMenu(menu);

}

/*点击menu菜单按钮发生事件*/

@Override

public boolean onOptionsItemSelected(MenuItem item) {

int item_id = item.getItemId();

if(item_id==1){ //清空历史记录

HistoryOprate.createXml(); //创建空的历史记录文件覆盖原文件

Intent intent = new Intent();

intent.setClass(HistoryActivity.this, HistoryActivity.class);

startActivity(intent);

HistoryActivity.this.finish();

}else{ //返回图片浏览器

Intent intent = new Intent();

intent.setClass(HistoryActivity.this, PictureBrowserActivity.class);

startActivity(intent);

HistoryActivity.this.finish();

}

return super.onOptionsItemSelected(item);

}

PictureBrowser.java中自定义适配器

/*ImageAdapter*/

public class ImageAdapter extends BaseAdapter{

private Context context;

int mGalleryItemBackground ;

public ImageAdapter(Context c){

context = c;

Typed ta = obtainStyledAttributes(R.styleable.Gallery);

mGalleryItemBackground = ta.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0);

}

@Override

public int getCount() {

return Integer.MAX_VALUE;//传入一个很大的值以实现循环滑动

}

@Override

public Object getItem(int position) {

return position;

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View arg1, ViewGroup arg2) {

ImageView i = new ImageView(context);

/*images文件夹下无图片时调用*/

if(pic_res.isEmpty()){

i.setImageResource(R.drawable.null_ga);

return i;

}

/*images文件夹下有图片时调用*/

else{

i.setImageURI(pic_res.get(position%pic_res.size()));

i.setAdjustViewBounds(true);

i.setLayoutParams(new Gallery.LayoutParams(

LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));

i.setBackgroundResource(mGalleryItemBackground);

return i;

}

}

}

histoty.xml页面选择一项

/*ListView 中某项被选中后的逻辑*/

@Override

protected void onListItemClick(ListView l, View v, int position, long id) {

Map data = mData.get(position);

if(!data.get("title").toString().equals("无记录")){ //跳转至历史图片浏览

Intent intent = new Intent();

intent.setClass(HistoryActivity.this,ViewActivity.class);

Bundle bundle = new Bundle(); //传递参数

bundle.putString("name", data.get("title").toString());

bundle.putString("path", data.get("info").toString());

intent.putExtras(bundle);

startActivity(intent);

HistoryActivity.this.finish();

}

super.onListItemClick(l, v, position, id);

}

本文来源:https://www.2haoxitong.net/k/doc/a6ae90def524ccbff021842a.html

《[毕业论文]基于安卓的图片浏览器的设计与实现.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式