软件工程毕业设计(论文)-基于Android手机辅助系统
青岛大学本科生毕业论文(设计) 方萌
本科毕业论文(设计)
题 目: 基于Android手机辅助系统
学 院: 国际学院
专 业: 软件工程
姓 名:
指导教师:
2011年 5月23日
1
青岛大学本科生毕业论文(设计) 方萌
目 录
第一章 序言..................................................................................................................................... 1 1.1 设计背景 ............................................................................................................................... 1 1.2 设计目标 ................................................................................................................................ 1
1.2.1短信群发 .................................................................................................................. 1
1.2.2来电管家 .................................................................................................................. 2
1.2.3多彩手电筒 .............................................................................................................. 2
1.2.4电蚊香 ...................................................................................................................... 2 1.3 项目设计原则 ........................................................................................................................ 3
1.3.1实用性原则 .............................................................................................................. 3
1.3.2可控性原则 .............................................................................................................. 3
1.3.3占用资源少的原则 .................................................................................................. 3
1.3.4易扩展性原则 .......................................................................................................... 3
1.4设计框架 .................................................................................................................................. 3第二章 系统分析 ............................................................................................................................. 5 2.1 需求分析................................................................................................................................ 5 2.2 技术可行性 ............................................................................................................................ 5
2.2.1面向对象编程技术 .................................................................................................. 5
2.2.2程序语言的选择 ...................................................................................................... 6
2.2.3操作可行性 .............................................................................................................. 6 2.3 环境可行性分析 ...................................................................................................................... 7
2.3.1软件环境 .................................................................................................................. 7
2.3.2硬件环境 .................................................................................................................. 7 2.4 系统结构可行性分析 .............................................................................................................. 7 第三章 系统设计 ............................................................................................................................. 8 3.1 总体设计 ................................................................................................................................. 8 3.2 数据库设计 ............................................................................................................................. 8
3.2.1数据库的需求分析 .................................................................................................. 8
3.2.2数据库表的具体设计 .............................................................................................. 9 3.3 详细设计 ............................................................................................................................... 10
3.3.1目标实现 ................................................................................................................ 10
3.3.2具体设计 ................................................................................................................ 10 3.4 数据模块架构图 .................................................................................................................... 11 3.5 各数据模块详细架构 ............................................................................................................ 11
3.5.1短信群发模块文件架构 ........................................................................................ 11
3.5.2来电管家模块文件架构 ........................................................................................ 12
3.5.3电蚊香模块文件架构 ............................................................................................ 13
3.5.4手电筒架构 ............................................................................................................ 13 第四章 系统实现 ........................................................................................................................... 15 4.1主界面的实现 ........................................................................................................................ 15 4.2短信群发模块实现 ................................................................................................................ 19 4.3来电管家模块实现 ................................................................................................................ 42 4.4手电筒模块实现 .................................................................................................................... 49 4.5电蚊香模块实现 .................................................................................................................... 51
2
青岛大学本科生毕业论文(设计) 方萌
4.6开机启动程序的实现 ............................................................................................................. 52 4.7系统展望 ................................................................................................................................ 53 第五章 系统测试 ........................................................................................................................... 54 5.1 测试的定义和目的 ................................................................................................................ 54 5.2 测试的方法 ........................................................................................................................... 54 5.3测试发现的问题及解决
................................................................................................. 54
5.3.1短信群发测试 ........................................................................................................ 54
5.3.2来电管家测试 ........................................................................................................ 55
5.3.3其他模块的测试 .................................................................................................... 55 第六章
................................................................................................................................... 56 谢 辞 .......................................................................................................................................... 57 参考文献 ........................................................................................................................................ 58
3
青岛大学本科生毕业论文(设计) 方萌
第一章 序言
1.1 设计背景
当今通讯领域中,手机成为日常生活必不可少的工具,随着科学技术的发展,智能手机日趋发展成熟。2007年11月5日,Android手机操作系统脱颖而出,仅推出两年已超越称霸十年的诺基亚塞班系统,一跃成为全球最受欢迎的智能手机平台之一。Android系统不但应用于智能手机,也在平板电脑市场急速扩张。该系统是基于Linux内核的系统,早期由Google公司开发,后由开放手持设备联盟(Open Handset Alliance)开发。它采用了软件堆层(software stack,又名以软件叠层)的架构,主要分为三部分。底层Linux内核只提供基本功能;其他的应用软件则由各公司自行开发,部分程序以Java编写。Android为开源系统,开发灵活性更强,各种软件层出不穷,发展前景十分广阔。
智能手机改变人们使用手机的习惯,也放大人们对手机的想象。对目前形式的分析和对未来的展望,手机系统已经不仅限于通话和短信等内容,手机扩展功能日益发展壮大,利用手机里的各种基本功能,可以拓展更多更实用的软件,这不仅使用户更方便的利用手机,而且也激发了很多编程人员的创新思维。本程序就是利用android手机系统的各种功能实现有创意且实用的手机辅助系统。 1.2 设计目标
众所周知,手机的各项功能都是围绕用户的需求而开发的,以下功能设计的实现就是按照人们生活中经常用到的但系统中没有的功能,从而为android系统提供更好的用户体验。
1.2.1短信群发
1)此项功能不仅可以正常发送短信,而且可以发送对方的称谓。我们国家人民热情好客,逢年过节祝福不断。近几年随着移动事业的发展,以短信传递祝福的方式广为流传。而编辑短信逐条发送很麻烦,短信群发又感觉没有诚意,如果可以带上对方的姓名或昵称发送,会让被祝福者倍感亲切。发送的姓名可以随意更改,默认为联系薄里的姓名,选择后可以改为其他昵称。
2)定时发送的功能。在紧张忙碌的工作学习生活中,难免会遇到待发送的重要信息被遗忘,或者同一时间有其他的事情要做而耽误了短信的待发送。为了避免这些现象的发生,可以预先定时进行发送,而且不会影响非定时短信的发送。
1
青岛大学本科生毕业论文(设计) 方萌
若定时信息未到时间,信息内容、发送时间及联系人可以增删改查,以防止发送失误带来的尴尬。
1.2.2来电管家
1)自动回复功能。当用户有急事来不及或者不方便接听电话和短信,此功能可以帮用户及时回复对方,以便让对方知道本人的当前状态或其他内容。此功能可以选择回复对象、回复内容,也可以选择对短信回复、对来电回复、对短信和来电都回复。当然,为了防止恶意来电,每次启用该功能后,无论短信还是来电,每人只限一次回复。
2)翻转静音功能。这是模仿诺基亚手机的一项功能,对于如此畅销的android系统而言,若没有此功能确实是个遗憾。用过的人都很清楚此功能的趣味性和实用性,比如在会议室或者其他不方便使用铃声的场合,而忘了调成静音模式,只要开启该功能,当来电铃声响起时,就可以翻转手机快速变为静音模式,从而有效防止打扰他人和避免自己的尴尬。
1.2.3多彩手电筒
此功能的实现也为该系统增添了趣味性和实用性。一般人们都不会随身携带手电筒,除非必要的时候。但是如果没有防备时,手头没有一个照明的东西,确实带来危险和不便。而手机是人们生活中都会随身携带的物品之一,如果安装了该软件,只要打开屏幕,亮度会自动调到最大,这会有很好的照明效果。而且内设了多种颜色供用户选择,其中有一种为紫色,可以用来模拟紫外线灯进行验钞等,虽然不能与真的紫外线灯媲美,但仍有其功效。
1.2.4电蚊香
炎热的夏季,蚊虫滋生快,被蚊子叮咬确实奇痒难忍,启动该功能后,手机的音频外设会放出让蚊虫难以忍受的频率波段,从而达到驱蚊的效果;而人耳对此频率的感应能力不是很强。
2
青岛大学本科生毕业论文(设计) 方萌
1.3 项目设计原则
1.3.1实用性原则
设计此软件的初衷是方便用户使用,本程序的各项功能都是围绕用户需求设计,实用性是此软件的最基础原则,围绕这个基础进行创新型扩展。 1.3.2可控性原则
为了方便用户的使用,每个功能都可由用户自主控制,参数也可由用户自定义,这就迎合了大部分人的使用习惯,充分体现以人为本。该原则的目的就是软件适应用户,而不是用户适应软件。
1.3.3占用资源少的原则
此软件是安装在手机操作系统上使用,因为目前的大部分手机CPU和内存都比不上电脑的配置,如何节省资源开销已经成为手机编程中必不可少的环节。 1.3.4易扩展性原则
此软件的架构是按照可扩展性设计的,这样做是为了方便以后升级和扩展更多更实用的功能,易于软件优化,从而使该软件的灵活性增强,功能更加完善,运行更加稳定。
1.4设计框架
此手机辅助系统采用Java语言设计,在功能上分为四个模块:短信群发模块,来电管家模块,手电筒模块,电蚊香模块。而每个模块多由界面部分和功能部分组成,除手电筒模块外,其余模块均有服务功能,即后台运行机制。此系统主要由服务、广播和多线程机制有机的统一于一个整体。短信群发模块分为界面部分,联系人读取部分,修改列表部分,手机发送短信机制,定时机制等方面进行设计与实现;来电管家模块分自动回复和翻转静音两大部分,自动回复从界面设计和广播监听与后台服务的结合进行阐述,翻转静音从手机摆放角度监听和广播监听的结合进行阐述;手电筒模块主要在屏幕亮度方面着手;电蚊香则从系统后台播放音乐方面着手。
3
青岛大学本科生毕业论文(设计) 方萌
在论文设计方面,采用从整体到细节,从重点到难点的写作思路对该系统的设计实现进行描述。首先分析了当今智能机产业的发展背景和前景,介绍了手机辅助系统对用户工作和生活的影响和用户对该系统的需求,分析了实现本系统的可行性,而本文章重点内容是手机辅助系统的设计和实现方法,最后对该系统各个功能模块进行测试评价,论述该系统的优缺点和对本软件的前景展望。在本文中,短信群发和来电管家模块将是主要的论述部分。
4
青岛大学本科生毕业论文(设计) 方萌
第二章 系统分析
2.1 需求分析
在智能手机日益发展壮大的今天,手机辅助系统使智能手机功能的多样化和人性化成为可能。通过手机辅助系统,我们可以更方便的应用和整合手机的各种软硬件,拓展出更多更实用的功能。通过手机辅助系统中的短信群发,我们可以更方便的发送带有称谓的短信,从而提升在人际关系中的友好程度和在好友圈中的受欢迎程度;通过手机辅助系统中的来电助手,我们可以随心所欲的定制自动回复功能,避免无人接听给对方带来的担忧,使智能手机更加人性化;通过手机辅助系统中的手电筒,可以为我们照亮光线不好的环境,如无电灯的楼梯,这样可以有效的避免黑暗为我们带来的不便,而且又不必随身携带手电,实现一机多用;通过手机辅助系统中的电蚊香,我们可以在多蚊虫的环境中避免被蚊虫叮咬而带来的痛苦,从而使我们不必分散精力,提高工作和学习效率。 2.2 技术可行性
2.2.1面向对象编程技术
面向对象程序设计(Object-Oriented Programming)是一种起源于六十年代,发展已经将近三十年的程序设计思想。其自身理论已十分完善,并被多种面向对象程序设计语言(Object-Oriented Programming Language)实现。对象是对现实世界实体的模拟,由现实实体的过程或信息特性来定义。一个对象可被认为是一个把数据(属性)和程序(方法)封装在一起的实体,这个程序产生该对象的动作或对它接受到的外界信号的反应。这些对象操作有时称为方法。区别面向对象的开发和传统过程的开发的要素有:对象识别和抽象、封装、多态性和继承。
面向对象的核心是对类的应用。在本程序中大量用到面向对象技术,每个功能的实现都离不开对以下类的继承:Activity(动作类)、Services(服务类)和Broadcast(广播类)。这些类均在Android SDK中提供接口。 1) Activity:android系统与用户进行交互的接口,用户对android系统进
行操作都是通过activity类来完成。此类要依附于界面,对用户是可见
的。
2) Services:与Activity类似,区别在于不用依附于见面,可以后台运行
5
青岛大学本科生毕业论文(设计) 方萌
动作指令。
3) Broadcast:系统每运行一个事件都会触发一个广播,通过广播监听器可
以对相应事件做出反应。
2.2.2程序语言的选择
, Java ME
Java ME(Java Platform,Micro Edition),这个版本以前称之为 J2ME。J2ME 为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒等)上运行的应用程序提供一个健壮且灵活的环境。Java ME 在用户界面、网络
、安全模型等方面具有很强的灵活性和稳定性。基于 Java ME 规范的应用程序只需编写一
用于许多设备,而且可以利用每个设备的本机功能。Java语言提供次,就能够
类的继承,Android系统的编程就很好的利用了这一性质。总之,Java语言是一个面向对象的程序设计语言。这种优良的特性使Java应用程序具有无比的健壮性和灵活性,而且通过内置的API(应用程序接口)可大大节省资源开销,提高编程效率。
本系统是基于Android开发平台的软件,因为Android顶层的应用软件大部分都是用java语言开发,而要与系统进行关联,不可避免的用到了Android SDK提供的API,通过此API可将该软件与Android系统有机的融合为一个整体。 , XML
XML即可扩展标记语言,是一种简单数据存储语言,类似于HTML,都是
通用标记语言。Xml是在Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。XML与HTML的不同点是:XML的主要作用是存储数据,而HTML是用来定义数据的。扩展标记语言XML使用一系列简单的标记描述数据,建立和保存数据比较方便。虽然XML占用的空间相对于二进制数据存储占用的空间更多,但XML极其简单易于掌握和使用。
在Android编程中,要用XML文件进行界面布局设置。本程序不仅用XML文件设置界面,也用它作为数据库存储数据(Preference存储模式)。 2.2.3操作可行性
本系统只要求具有一定的手机操作经验,因为Android系统本身操作就很简单,本程序中全部的控件均继承自Android,所以用户对控件本身的操作不会陌生。在本程序中,每进行一步操作都会有相应的提示,而且每个功能界面都会提供帮助信息,只要有一点手机操作经验,看过提示后,对本软件的操作就会非常清楚。
6
青岛大学本科生毕业论文(设计) 方萌
2.3 环境可行性分析
2.3.1软件环境
软件运行环境:Android操作系统 2.1 update1版本
语言环境:简体中文
编译环境:Windows7 32bit操作系统
编译工具:Eclipse 3.6+Android SDK 2.3.2硬件环境
软件测试机型:三星GT-I5508
编译环境:联想天逸 F41a, CPU IntelCore2 1.67GHz,RAM 2G 2.4 系统结构可行性分析
Android SDK 提供了一个视图控件——GridView,用于以网格的形式陈列内容。本软件利用此结构,以功能为单位将各图标和名称陈列于此视图中,这种结构的优点是使软件界面简洁大方,对各功能一目了然,易于用户操作,是一种人性化的界面设计格式;另一方面,这种结构形式有利于软件开发过程中进行软件管理,增加新功能,删除无用功能。
7
青岛大学本科生毕业论文(设计) 方萌
第三章 系统设计
3.1 总体设计
本系统的主要任务是辅助手机用户更方便的管理和使用手机的各项基本功能,主要分为一下几个功能模块:主界面模块,短信群发模块,手机照明模块,来电管理模块,电蚊香模块。模型结构如图3.1所示:
手机辅助系统
主界面
短信群发 手机照明 来电管理 电蚊香
选短选自翻播
择信择动转放
联发颜回静声
系送色复音波 人
修删定插回回来翻改除时入复复电转称所系称对内动后谓选统谓象容作动 作
图3.1 手机辅助系统结构图
3.2 数据库设计
3.2.1数据库的需求分析
根据项目的需要,本系统将建立如下数据库表单:
来电管家界面表单(fm.app.aa_preferences.xml):用于存储来电管家的设置参数;
电蚊香状态表单(MosPre.xml):用于存储电蚊香功能的开启状态;
短信群发状态表单(SmssPre.xml):主要用于存储定时发短信的参数;
本程序状态表单(AAPre.xml):主要存储本程序中各个功能的开启状态,可
8
青岛大学本科生毕业论文(设计) 方萌 使手机重启后能继续运行相应程序。
3.2.2数据库表的具体设计
表3.1来电管家界面表单(fm.app.aa_preferences.xml)
boolean false 是否开启自动回key_manager_leave_check
复
String I am not 回复内容 key_manager_leave_edit_mess
here,please wait a age
moment
String phone 回复来电动作 key_manager_leave_list_action
String friends 回复对象 key_manager_leave_list_humen
boolean false 是否打开翻转静key_manager_overturn_check
音
boolean false 翻转后动作 key_manager_overturn_list_action
表3.2电蚊香状态表单(MosPre.xml)
int 0 是否开启避蚊功能 mos_status
表3.3短信群发状态表单(SmssPre.xml)
boolean false 是否插入称谓 isinsert
boolean false 是否定时发送 istimer
String null 称谓前字符串 message_before
String null 称谓后字符串 message_after
int 1900 定时年 year
int 1 定时月 month
int 1 定时日 day
int 0 定时小时 hour
int 0 定时分钟 minute
int 0 选择的联系人数 count
String null 选择联系人姓名 name[]
String null 选择联系人电话 phone[]
表3.4本程序状态表单(AAPre.xml)
boolean false 是否有定时发短信任Smss_Timer
9
青岛大学本科生毕业论文(设计) 方萌
务
boolean false 是否开启自动回复 Manager_Leave
boolean false 是否开启翻转静音 Manager_Overturn
3.3 详细设计
3.3.1目标实现
本系统主要目的是辅助用户更方便地使用手机,突出实用功能。具体地讲,本系统通过手机固有的接口,从短信功能、来电管理功能,照明功能、避蚊功能(播放功能)出发,实现辅助作用,充分发挥智能机的优点,将实用性尽可能扩展到最大。具体实现如下目标:
, 短信群发功能
, 手机照明功能
, 自动回复功能
, 翻转静音功能
, 电蚊香功能
, 可后台运行,建立服务架构
, 重启后仍然有效,实现开机启动
, 运行安全可靠稳定
, 占用尽可能少的资源
, 适合各种手机屏幕分辨率
, 对Aandroid各种版本兼容性强
3.3.2具体设计
手机辅助系统是基于Android 系统平台下的应用软件,针对Android手机用户开发。主要的功能模块有:短信群发,来电管家,多彩手电筒,电蚊香。以下是对各个功能模块的具体设计:
短信群发:主要包括群发短信,定时群发,可插入称谓,对所选联系人的删除和修改操作。
来电管家:对来电和短信自动回复,可以自定义回复事件是来电还是短信,可以自定义回复内容,可以自定义回复对象是好友还是全部回复,重启仍然可以正常运行。
多彩手电筒:屏幕亮度为最大,避免手机进入待机状态,颜色可由用户选择,
10
青岛大学本科生毕业论文(设计) 方萌
增加紫色验钞光。
电蚊香:播放驱蚊声波,可后台运行,若功能打开,重启后仍然有效。
3.4 数据模块架构图
此图为本软件的总架构图,显示了各个功能模块之间的关系和后台服务和前台操作的关系, 简单阐明了系统运行的机制,具体结构如图3.2所示:
AA.java
主界面
SmssContact.java选择联系人
Smss.java Manager.java Mos.java Light.java
短信群发 来电管家 电蚊香 手电筒
SmssService.javaMosService.javamanagerOverturnmanagerService.java
发送短信服务 电蚊香服务 Service.java翻转自动回复服务
静音服务
根据状态信息启动服务 记录状态信息
AAPre.xml AABroadcast.java用
于处理开机事件
开机读取状态信息 开机
图3.2 系统数据模块架构图
3.5 各数据模块详细架构
3.5.1短信群发模块文件架构
短信群发模块通过SmssContact.java调用系统中的联系人列表;当启动定时服务时,通过AlarmManager触发SmssService后台服务发送短信,当触发服务的同时,将开机项目表单中的短信定时服务状态改为活动状态,如下图3.3
11
青岛大学本科生毕业论文(设计) 方萌
所示:
返回联系人数据
直接发送
Smss.java SmssContact.java
短信群发 读取联系人列表
发送短信给所Alarm
选的联系人 Manager
定时
SmssService.java AAPre.xml 定时发送 后台发短信服务 开机启动项表单
图3.3短信群发模块运行架构示意图
3.5.2来电管家模块文件架构
来电管家模块分为自动回复和翻转静音两个功能,通过设置界面(PreferenceScreen)可由用户直接启动两个功能,对设置的更改触发事件,运行相应的服务,并且更新开机启动项表单的信息,以便开机后仍然可以正常运行。
启动自动回复功能后,服务中会建立用来监听来电或短信的广播监听器,当来电或来短信时,程序读取电话号码,根据用户的自定义设置进行相应的回复动作;启动翻转静音功能后,即启动了含有监听来电广播监听器的服务,原理同上,当来电时,触发来电广播监听器,而其中又注册了一个监听手机角度的类模块,若此时手机角度小于-120?,即手机翻转过来,就进行相应的静音操作。运行机制可用图3.4表示:
12
青岛大学本科生毕业论文(设计) 方萌
Manager.java AAPre.xml 来电管家 更新状态列表
managerService.java managerOverturnService.java 手机静音
自动回复服务 翻转静音服务
smsReceiver callReceiver callReceiver mSensorListener
短信广播监听器 来电广播监听器 来电广播监听手机角度监听器
器
读取电话号码 来电话 来短信
并回复短信 用户将手机翻转
图3.4来电管家模块运行架构示意图
3.5.3电蚊香模块文件架构
电蚊香模块的原理是通过系统从后台循环播放一段音频波段,此模块设计比较简单,运行架构如下图3.5所示:
Mos.java MosService.java
电蚊香模块 电蚊香服务
更新状态表单
AAPre.xml 驱赶蚊虫
服务状态表单
图3.5电蚊香模块运行架构示意图
3.5.4手电筒架构
手电筒的实现较为简单,启用该功能后,程序首先保存当前的亮度,然后将亮度调到最大,并全屏显示,背景颜色默认为白色。退出该功能后将屏幕亮度参数恢复到之前的值。运行机制如图3.6所示:
13
青岛大学本科生毕业论文(设计) 方萌
Light.java
手电筒模块
开启 退出
保存屏幕亮度值 根据之前保存的亮度因数
恢复屏幕亮度 将屏幕亮度调为最大 手机照明 背景默认为白色
背景颜色可调
图3.6手电筒运行示意图
14
青岛大学本科生毕业论文(设计) 方萌
第四章 系统实现
此系统分为四个模块分别进行实现,这些模块既相互独立,又相互联系。所谓相互独立,是指各功能之间是平行关系,功能之间没有必然的联系;所谓相互联系,是指通属于一个主界面控制,使整个系统成为一个有机的整体。下面分别介绍各模块的实现代码及效果图。
4.1主界面的实现
此部分的代码在AA.java中,用来显示所有功能模块,以便进入相应模块进行操作。此界面采用GridView布局,使界面简洁大方,一目了然,充分体现人性化设计理念。
首先要建立一个GridView的适配器布局,用来定义GridView的格式,本程序中用上图标下文字的显示方式,此代码在layout/grid.xml文件中,实现代码如下:
建立GridView适配器文件(AAGridViewAdapter.java)
/*创建GridView方法*/
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater factory=LayoutInflater.from(_con);
/*使用grid.xml定义每个item的Layout*/
View v=(View)factory.inflate(R.layout.grid, null);
/*取得View*/
ImageView iv=(ImageView)v.findViewById(R.id.icon);
TextView tv=(TextView)v.findViewById(R.id.text);
/*设置显示的Image与文字*/
iv.setImageResource(_icons[position]);
15
青岛大学本科生毕业论文(设计) 方萌
tv.setText(_items[position]);
return v;
}
建立主界面的布局,采用相对布局(RelativeLayout),在其中包含一个
GridView,设置每行显示的数量为3:
/>
将做好的图标存到工程文件夹下的res/drowable中,声明图标数组和相对
应的字符数组:
//定义GridView的图标
private int[] icons={
R.drawable.message,
R.drawable.light,
R.drawable.manager,
R.drawable.mos
};
//定义GridView的显示文字
private int[] items={
R.string.aa_smss,
R.string.aa_light,
R.string.aa_manager,
R.string.aa_mos
};
将适配器与图标和文字进行连接
gv=(GridView)findViewById(R.id.GridView_aa);//定义一个GridView对象
/*使用自定义的AAGridViewAdapter设置GridView里面的Item内容*/
AAGridViewAdapter gv_adapter=new
AAGridViewAdapter(this,items,icons);
gv.setAdapter(gv_adapter);
声明一个click点击事件,用于用户点击相应图标进入对应的功能模块,因
为每个GridView都有一个position,我们可以用这个变量辨别用户单击的是哪
16
青岛大学本科生毕业论文(设计) 方萌 个图标:
public void onItemClick(AdapterView> parent, View v, int position,
long arg3) {
Intent intent=new Intent();
switch(position){
case 0://进入短信群发
intent.setClass(AA.this,Smss.class);
startActivity(intent);
break;
case 1://进入手电筒
intent.setClass(AA.this,Light.class);
startActivity(intent);
break;
case 2://进入通信管家
intent.setClass(AA.this,Manager.class);
startActivity(intent);
break;
case 3://进入电蚊香
intent.setClass(AA.this,Mos.class);
startActivity(intent);
break;
default:
break;
}
}
主界面的显示部分到此结束,效果如图4.1:
17
青岛大学本科生毕业论文(设计) 方萌
图4.1主界面的效果图
在主界面内建立一个“关于”对话窗口,按MENU键打开,里面存放软件的信息。先声明一个MENU菜单:
public boolean onCreateOptionsMenu(Menu menu) {
// TODO 等待其他选项加入
menu.add(0, 0, 0, R.string.str_about);
return super.onCreateOptionsMenu(menu);
}
建立点击事件,每个点击对象都有一个ID,在此只建立一个MENU对象,当点击后打开关于对话窗口:
public boolean onOptionsItemSelected(MenuItem item) {
// TODO 等待其他选项动作加入
super.onOptionsItemSelected(item);
switch(item.getItemId()){
case 0:
helpDialog();//在此调用“关于”对话窗口
break;
}
return true;
}
对话窗口的实现很简单,实例化一个AlertDialog对象即可: private void helpDialog(){
new AlertDialog.Builder(this)
.setTitle(R.string.str_about)
.setMessage(R.string.app_about)
.setPositiveButton(R.string.str_ok,
18
青岛大学本科生毕业论文(设计) 方萌
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface arg0, int arg1) {
}
}).show();
显示效果如图4.2所示:
图4.2关于对话框的显示
需要注意的是,本程序的文本显示内容,如以上代码中的
“R.string.str_about”均存放在res/values/strings.xml文件里,这样做的好处是便于更改文字内容,可方便实现语言的转换。当然,目前只有中文,可根据需要,只要将该文件里的中文翻译为其他语言即可更改为另一个语言版本的软件。
4.2短信群发模块实现
短信群发功能分一下几个部分实现:主界面部分,添加联系人,联系人称谓的删除和修改,短信群发系统,插入联系人称谓,定时服务系统。此部分的主要功能是群发短信并可由用户自定义是否发送称谓,也可选择定时发送,可实现定时发送与即时发送互不影响。
?短信群发的主界面
此功能模块界面实现的主要难点在于listview的重写方法,listview是以可滚动列表的形式显示固定格式的内容,在此模块中,用以显示已选好的联系人姓名。
19
青岛大学本科生毕业论文(设计) 方萌
首先是界面布局,是以相对布局(RelativeLayout)实现的。之所以采用这种
布局,是为了符合各个屏幕的分辨率,不会因为屏幕的大小而使其内容的位置改
变,符合大众化的需求。代码在Smss.xml中:
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
/>
几乎所有的自定义ListView都要使用适配器定义格式,在此也不例外,文
件为SmssAdapter.java。与之前的适配器建立步骤一样,首先建立适配器布局
文件,名为smslv.xml,同样采用相对布局,格式为并列的两个TextView:
20
青岛大学本科生毕业论文(设计) 方萌
下面就要定义适配器,继承系统的SimpleAdapter类,引用上面提到的布局格式,代码写在SmssAdapter.java文件中:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.smslv, null);
}
TextView tN = (TextView)
convertView.findViewById(R.id.txt_smss_name);
tN.setText((String) mList.get(position).get(SELECTED_NAME));
TextView tR = (TextView)
convertView.findViewById(R.id.txt_smss_report);
tR.setText((String) mList.get(position).get(SEND_REPORT));
return convertView;
}
此时短信群发界面的已选择联系人列表建立完成了,这个ListView中的内容就是从选择联系人界面选择的联系人姓名。因为先要进入子页面选择联系人,而后返回父窗体时显示内容,所以用startActivityForResult抛出,用此方法返回父窗体就会执行onActivityResult()方法:
……
startActivityForResult(intent,0); ……
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
super.onActivityResult(requestCode, resultCode, data);
listView = (ListView)findViewById(R.id.smslv);
switch(resultCode){
case RESULT_OK:
……
default:
break;
}
……
}
21
青岛大学本科生毕业论文(设计) 方萌
此模式的原理是子页面将选择的内容存入ArrayListExtra空间的变量中,然后用getStringArrayListExtra将内容取出,子页面存入方法在接下来的部分中介绍,以下为父页面取出记录的内容,记录为所选的用户名和相应的电话号码,取出后将内容分别存放在arraylist变量name和phone中:
name=data.getStringArrayListExtra("str_name");
phone=data.getStringArrayListExtra("str_phone");
name.trimToSize();//节省资源开销
phone.trimToSize();
将用来显示的arraylist(这里实例化为al1)变量清空,以防重复显示:
al1.clear();
定义哈希map,此格式变量以键值对的形式存储内容,下面用循环的方式分别将选出的联系人姓名添加到al1中:
for(int i=0;i
map = new HashMap();
map.put(SELECTED_NAME, name.get(i));
al1.add(map);
}
将listview与它的适配器进行关联:
String[] from = { SELECTED_NAME, SEND_REPORT };
int[] to = { R.id.txt_smss_name, R.id.txt_smss_report };
mSmssAdapter=new SmssAdapter(this, al1, R.layout.smslv, from, to);
listView.setAdapter(mSmssAdapter);
break;
这样就把所选的内容逐条显示在listview中了。主界面效果及选择联系人后的效果如图4.3所示:
图4.3短信群发主界面。左图为未选择联系人界面,右图为选择联系人返回后的界面
22
青岛大学本科生毕业论文(设计) 方萌
?选择联系人
当在短信群发主页面点击“选择联系人”按钮时,就会进入选择联系人的界面,启动此页面继承的Activity——SmssContact,此Activity在SmssContact.java中实现。
首先实现进入选择联系人页面,在androidSDK中要使一个Activity启动另一个Activity的就是利用intent方法,格式如下:
Intent intent=new Intent();
intent.setClass(父类Activity,子类Activity);
startActivityForResult(intent,0);
在Smss(联系人主界面)的activity中,用如下方法将活动抛给SmssContact类,此方法写在“选择联系人”的点击事件中。当点击“选择联系人”后,系统就会读取联系人数据,然后将联系人显示与listview中,在这个过程中,系统会出现“假死”状态,所以,应在这期间设置一个dialog窗口,用来提示用户正在读取数据,而不是死机现象,这样更体现出人性化的设计思想理念。
首先定义dialog的标题和内容:
final CharSequence
strDialogTitle=getString(R.string.dialog_smss_readcontacttitle);
final CharSequence
strDialogBody=getString(R.string.dialog_smss_readcontactbody);
然后显示dialog:
//显示Dialog
sendmsg_Dialog=ProgressDialog.show(
Smss.this,
strDialogTitle,
strDialogBody,
true
);
在显示dialog后,启动一个线程来调用选择联系人的Activity,当完成对选择联系人窗口的启动后,dialog销毁,代码如下:
……
new Thread(new Runnable(){
public void run() {
//new一个Intent对象,并制定class
Intent intent=new Intent();
intent.setClass(Smss.this,SmssContact.class);
startActivityForResult(intent,0);//此函数可以返回被叫activity
传来的数据
sendmsg_Dialog.dismiss();
}
}).start();
……
23
青岛大学本科生毕业论文(设计) 方萌
图4.4读取联系人时的dialog
完成上面的步骤就进入“选择联系人”页面,利用游标cursor读取手机里的联系人,方法如下:
//取得电话本中开始一项的光标
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext())
{
Map map = new HashMap();
// 取得联系人名字
int nameFieldColumnIndex =
cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME); String name = cursor.getString(nameFieldColumnIndex);
// 取得联系人ID
String contactId =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
在android2系列以后,每个联系人的电话可存放多个,所以要再定义一个游标来循环读取电话号码:
Cursor phone =
cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
map.put(NAME, name);
// 取得电话号码(可能存在多个号码),在此处无用
while (phone.moveToNext())
{
String strPhoneNumber =
24
青岛大学本科生毕业论文(设计) 方萌
phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds
.Phone.NUMBER));
map.put(PHONE_NUMBER, strPhoneNumber);
}
al.add(map);
phone.close(); //关闭游标
}
cursor.close();//关闭游标
本页面的格式与之前的设置类似,都是相对布局格式,在此就不必赘述,唯一不同的是listview的格式有所改变(写在smscontact.xml文件中):
在此特别注意以上代码checkbox中的如下三行:
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
如果不将checkbox的焦点设为false,它会覆盖listview,从而导致点击listview时不能获得焦点。而为了使checkbox可选,可在listview的点击事件中用代码实现:
25
青岛大学本科生毕业论文(设计) 方萌
public void onItemClick(AdapterView> parent, View view, int position, long id) {
CheckBox checkBox =
(CheckBox)view.findViewById(R.id.multiple_checkbox);
checkBox.toggle();//切换状态
mSimpleAdapter.Check_map.put(position, checkBox.isChecked());
……}
为了防止向变量中传入空值,若用户没有选择联系人,“确定”按钮就会失效,原理是统计被选择的checkbox个数,若个数为0,则按钮失效:
if(checkBox.isChecked()){
checked_count+=1;
}else{
checked_count-=1;
}
//若多选框为空则按键失效
if(checked_count==0){
btn_smscontact_accept.setEnabled(false);
}else{
btn_smscontact_accept.setEnabled(true);
}
下面实现将所选的联系人信息回调给上一个Activity,即Smss。因为此Activity是用startActivityForResult函数调出的,要传回数据到主Activity,需要将数据分别存放到名为“str_name”和“str_phone”的Extra空间变量中,用如下代码实现:
Uri uri = Uri.parse("back info");
Intent data = new Intent(null, uri);
str_name.trimToSize();//最小化内存系统开销
str_phone.trimToSize();
data.putStringArrayListExtra("str_name", str_name);
data.putStringArrayListExtra("str_phone", str_phone);
setResult(Activity.RESULT_OK, data);
SmssContact.this.finish();
最终运行效果图如图4.5所示:
26
青岛大学本科生毕业论文(设计) 方萌
图4.5选择联系人界面,左图为为选择时效果,右图为选择后的效果
当点击添加按钮后,页面返回短信群发主页面,效果如4.3右图所示,在此不必重复贴图。
?联系人称谓的删除和修改
选择好联系人以后,就可以根据联系人列表逐条发送短信了,用户可选择在短信内容中插入联系人称谓,称谓默认是系统中的姓名,若用户对称谓不满意,可长按其对应的列表项,则会弹出修改和删除的对话框。长按键的事件里实例化一个对话框即可:
class listLongListener implements OnItemLongClickListener{ public boolean onItemLongClick(AdapterView> arg0, View arg1,
final int i, long arg3) {
android.content.DialogInterface.OnClickListener listener1=new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { ……
}
}
};
String[] menu={getString(R.string.altdialog_smss_list1_rename),
getString(R.string.altdialog_smss_list1_delete),
getString(R.string.altdialog_smss_list1_clear)};
new AlertDialog.Builder(Smss.this)
.setTitle(name.get(i))
.setItems(menu, listener1)
.setNegativeButton(getString(R.string.str_cancel),
new DialogInterface.OnClickListener(){
27
青岛大学本科生毕业论文(设计) 方萌
public void onClick(DialogInterface dialog, int which) {
}
}).show();
return false;
}
}
实现效果如图4.6所示:
图4.6列表长按弹出窗口
这里的which就代表弹出列表的ID,这里用switch选择判断语句对用户点
击的列表项目进行判断:
switch(which){
case 0://选择item为更改称谓
……
break;
case 1://选择item为从列表中删除
……
break;
case 2://选择item为清空列表
……
break;
default:
……
break;
点击列表第一项,即可弹出更改称谓对话框,同时对存储称谓的变量和用于
28
青岛大学本科生毕业论文(设计) 方萌
显示称谓列表的变量进行更新,之前已说明过,name是一个arraylist类型的数组,所以要修改相应的内容,要调用set()方法进行修改,al1同理。同时将内容更新到al1中,然后用notifyDataSetChanged()方法对列表的显示进行更新,需要注意的是,若修改后的成为为空,则不作处理,仍为原来的称谓,代码如下: /* create更改称谓时弹出的Dialog */
LayoutInflater factory = LayoutInflater.from(Smss.this); AlertDialog renameDialog=new AlertDialog.Builder(Smss.this).create(); myView=factory.inflate(R.layout.smsalertdialog_rename,null); renameEdit=(EditText)myView.findViewById(R.id.renameEdit); renameEdit.setText(name.get(i));
android.content.DialogInterface.OnClickListener listener2=
new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) {
if(!renameEdit.getText().toString().equals("")){
name.set(i, renameEdit.getText().toString());//更改称谓(发送信息时以name phone为准)
// 更新列表
Map map = new HashMap();
map.put(SELECTED_NAME, name.get(i));
SmssAdapter newsmssAdapter=(SmssAdapter)listView.getAdapter();
al1.set(i, map);
newsmssAdapter.notifyDataSetChanged();
}
}
};
renameDialog.setView(myView);
renameDialog.setButton(getString(R.string.str_ok),listener2);//确定 renameDialog.setButton2(getString(R.string.str_cancel),//取消 new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
renameDialog.show();
修改称谓窗口效果如图4.7所示:
29
青岛大学本科生毕业论文(设计) 方萌
图4.7修改ccc为abc,左图为修改窗口,右图为修改结果
移除选出列表里某个联系人的原理同上,当在列表dialog中点击第二项时,即移除了相应的所选择的联系人,内容和列表显示的值都修改后,对listview进行刷新,即调用notifyDataSetChanged()方法:
name.remove(i);//移除所选内容
phone.remove(i);//同时移除phone,否则名称和号码无法对应
SmssAdapter newsmssAdapter=(SmssAdapter)listView.getAdapter();
al1.remove(i);
if(name.size()==0){//name和phone没有彻底变为null,而是成了“[]”,所以加以判断并赋值为null
name=null;
phone=null;
}
newsmssAdapter.notifyDataSetChanged();
效果如图4.8:
30
青岛大学本科生毕业论文(设计) 方萌
图4.8用户点击“从列表删除”移除了联系人aaa
用户点击第三项,则可将所选的所有联系人全部清除,此项可用于重新选择联系人时用。实现方法是调用arrylist的clear()方法:
name.clear();
phone.clear();
al1.clear();
经反复实验,发现此时应重新声明listview,才可完全清除列表中的内容,否则列表将不可用,因为列表对象返回空值:
listView = (ListView)findViewById(R.id.smslv);
String[] from = { SELECTED_NAME, SEND_REPORT };
int[] to = { R.id.txt_smss_name, R.id.txt_smss_report };
mSmssAdapter=new SmssAdapter(Smss.this, al1, R.layout.smslv, from, to);
listView.setAdapter(mSmssAdapter);
listView.setOnItemLongClickListener(new listLongListener()); ?短信发送机制
点击“发送”按钮时,可根据所选的联系人列表依次发送短信,在此可以调用系统自带的发送短信工具,具体步骤写在发送短信的sendMsgs()的方法里,要实现群发短信,必须进行循环调用发送短信的sendintent短信接口: // 移动运营商允许每次发送的字节数据有限,我们可以使用Android给我们提供的短信工具 SmsManager smsManager = SmsManager.getDefault();
PendingIntent sendIntent = PendingIntent.getBroadcast(Smss.this, 0, new Intent(), 0);
for(int i=0;i messages = smsManager.divideMessage(message);
if(phone.get(i)!=null){// TODO 应该加入判断电话格式的语句
for (String msg : messages) {
smsManager.sendTextMessage(phone.get(i),// 接收方的手机号码
null,// 发送方的手机号码
msg,// 信息内容
sendIntent,// 发送是否成功的回执
null// 接收是否成功的回执
);
}
Log.d("mydebug", "send"+i+phone.get(i)+message);//TODO 发送信息要真实的反馈,要在ListView显示发送结果
}else{
Log.d("mydebug", "noNum"+i);//TODO 如果联系人无电话号码,要给出提示。
}
}
以上发送短信的方法sendMsgs()在点击“发送”按钮时调用。为了更人性化,在发送时会弹出对话框让用户确认是否要发送,防止误操作: //发送短消息
……
final CharSequence
strDialogTitle=getString(R.string.dialog_smss_sendtitle); final CharSequence
strDialogBody=getString(R.string.dialog_smss_sendbody); if(!name.isEmpty() /*&&
etxt_message.getText().toString().equals(null)*/)
{
//弹出确认窗口,防止误操作
new AlertDialog.Builder(Smss.this)
.setTitle(R.string.altdialog_smss_send_title)
.setMessage(R.string.altdialog_smss_send_body)
.setPositiveButton(R.string.str_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
……
//发送消息
message=etxt_message.getText().toString();
//显示Dialog
sendmsg_Dialog=ProgressDialog.show(
32
青岛大学本科生毕业论文(设计) 方萌
Smss.this,
strDialogTitle,
strDialogBody,
true
);
效果如图4.9所示:
图4.9发送时确定
发送短信时,新建一个线程发送短信,防止假死现象。在发送过程中会有窗
口提示正在发送,当发送完毕后,关闭提示窗口:
new Thread(new Runnable(){
public void run() {
sendMsgs();
sendmsg_Dialog.dismiss();
}
}).start();
……
在发送时要判断联系人列表是否为空,不为空发送,若无联系人,则弹出
toast()提示用户:
Toast.makeText(Smss.this,R.string.Toast_smss_null,Toast.LENGTH_LONG).
show();
运行效果如图4.10:
33
青岛大学本科生毕业论文(设计) 方萌
图4.10发送联系人为空时toast提示
当正确发送后,会给出成功发送的提示,仍然调用toast提示方式: Toast.makeText(Smss.this, R.string.Toast_smss_Sended,
Toast.LENGTH_LONG).show();
效果如图4.11所示:
图4.11信息发送成功提示
?插入联系人称谓
在短信内容的光标位置可以插入联系人的称谓,其原理是将光标的前半部分与后半部分分别存放到字符串数组中,然后将存储联系人称谓的name[]数组放入中间,对应插入到接收人的短信内容中。在此用了一个方法来将编辑框中的内
34
青岛大学本科生毕业论文(设计) 方萌
容插入联系人姓名,在发送时直接调用此方法即可:
//插入联系人姓名并返回新字符串
public String insertContact(EditText et,String nmString){
String string = et.getText().toString();
String cut_sString = string.substring(0,
et.getSelectionStart());
String end_sString = string.substring(
et.getSelectionStart(), et.length());
return cut_sString + nmString + end_sString;
}
打开或者关闭插入称谓功能的实现很简单,是用android系统中的ToggleButton实现的,点击一次打开,再点一次关闭,打开或关闭时都会有toast提示:
tbtn_insert.setOnClickListener(new OnClickListener(){ public void onClick(View v) {
if(tbtn_insert.isChecked()){//是否发送联系人称谓
Toast.makeText(Smss.this, R.string.Toast_smss_isinsert, Toast.LENGTH_LONG).show();
}else{
Toast.makeText(Smss.this, R.string.Toast_smss_noinsert, Toast.LENGTH_LONG).show();
}}
});
显示效果如图4.12
图4.12打开或关闭插入称谓功能
35
青岛大学本科生毕业论文(设计) 方萌
点击“发送”按钮后,系统调用sendMsgs方法发送短信,在此方法中,系统会判断插入称谓功能是否开启,若开启,则调用插入方法将待发送的短信内容替换为插入称谓后的内容,再发送,代码如下:
public void sendMsgs() {
……
for(int i=0;i messages = smsManager.divideMessage(message);
if(phone.get(i)!=null){// TODO 应该加入判断电话格式的语句
for (String msg : messages) {
smsManager.sendTextMessage(phone.get(i),// 接收方的手机号码
null,// 发送方的手机号码
msg,// 信息内容
sendIntent,// 发送是否成功的回执
null// 接收是否成功的回执
);
}
}
……
为了检测系统是否真实的发送了短信,在sendMsgs方法中,添加一条Log记录,定义内容为“sendi/电话号码/短信内容”:
public void sendMsgs() {
……
Log.d("mydebug", "send"+i+"/"+phone.get(i)+"/"+message); ……
}
发送结果会直接反馈到编译器的LogCat中,可直观的浏览发送的每条短信。如图4.13:
图4.13LogCat中显示发送结果
在用户界面也可显示发送后的结果,其结果在编辑短信框的上方显示,也是一个edittext,但是处于不可编辑状态,而且长按后可将内容复制到短信编辑
36
青岛大学本科生毕业论文(设计) 方萌
框中:
图4.14用户发送后的效果显示,左图为插入称谓,右图为不插入称谓 ?定时服务系统
点击时间设定右边的ToggleButton,会开启或关闭定时服务功能。为防止发生错误,当不设定时间或者时间小于等于当时的时刻时,此按钮会灰显。
首先先建立一个判断时间合法与否的方法,此方法中的c1为系统时间,c2为用户设定的时间,当c1>c2时表示设置的时间不合法,返回false,否则返回true:
//判断设定时间是否合法
public boolean isAfter(int year,int month,int day,int hour,int minute){
Calendar c1=Calendar.getInstance();
Calendar c2=Calendar.getInstance();
c2.set(Calendar.YEAR, year);
c2.set(Calendar.MONTH, month-1);//转换为系统月份,从0计
c2.set(Calendar.DAY_OF_MONTH, day);
c2.set(Calendar.HOUR_OF_DAY, hour);
c2.set(Calendar.MINUTE, minute);
c2.set(Calendar.SECOND, 0);//整分
c2.set(Calendar.MILLISECOND, 0);
if(c1.getTimeInMillis()>c2.getTimeInMillis()){
return false;
}else
return true;
37
青岛大学本科生毕业论文(设计) 方萌
}
建立好了此方法,在定时发送的ToggleButton点击事件、发送短信的button点击事件、设置日期时间的button点击事件中都要用此方法判断时间的合法性。
当时间合法后,可点击ToggleButton打开定时功能,然后点击“发送”按钮,就会按照设定的时间发送短信,而定时的实现就是利用android系统的闹钟管理器AlarmManager,开启定时服务的代码如下:
//启动定时任务
public void startAlarmService(){
//先读取数据列表中的日期值:
SharedPreferences pres =
getSharedPreferences("SmssPre",Context.MODE_PRIVATE);
int year=pres.getInt("year", 1900);
int month=pres.getInt("month", 01);
int day=pres.getInt("day", 01);
int hour=pres.getInt("hour", 00);
int minute=pres.getInt("minute", 00);
// 将时间设置为定时的时间
Calendar calendar = Calendar.getInstance();// 代表当前时间的日历
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);//转换为系统月份,从0计
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);//整分
calendar.set(Calendar.MILLISECOND, 0);
//设定字符串,用于在通知中显示:
String
str0=getResources().getString(R.string.Toast_smss_starttimerService); String
str1=getResources().getString(R.string.smss_starttimer_Notify0)+year
+getResources().getString(R.string.smss_starttimer_Notify1)+month
+getResources().getString(R.string.smss_starttimer_Notify2)+day
+getResources().getString(R.string.smss_starttimer_Notify3)+hour
+getResources().getString(R.string.smss_starttimer_Notify4)+minute+getResources().getString(R.string.smss_starttimer_Notify5)+
getResources().getString(R.string.smss_starttimer_Notify6);
Notify.makeNotify(notifyId, this, Smss.class, R.drawable.timersms, str0, str0, str1);
//定义一个服务,用于后台发送短信:
Intent intent =new Intent(Smss.this,SmssService.class);
PendingIntent
sender=PendingIntent.getService(getApplicationContext(), 0, intent,
0);
38
青岛大学本科生毕业论文(设计) 方萌
//定义一个AlarmManager,并将服务与AlarmManager进行绑定:
AlarmManager am=(AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
sender);//set为执行一次后取消,(setRepeating为循环执行)
//更新开机启动列表:
UpDateAAPre("Smss_Timer",true);
//用Toast提示定时短信已开启,等待发送:
Toast.makeText(Smss.this,R.string.Toast_smss_starttimerService, Toast.LENGTH_SHORT).show();
}
此定时服务是在用户点击“发送”按钮并且在定时功能打开的情况下触发的,在button点击事件的代码如下:
if(!tbtn_timer.isChecked()){
……
}else{
if(isAfter(myear,mmonth,mday,mhour,mminute)){//TODO 启动定时发送服务
messagePre();//存储信息
setDateTime();//存储日期时间
updateContactPre();//存储联系人列表
readMessageAndShow();//显示信息
startAlarmService();//启动定时服务
}else{
tbtn_timer.setEnabled(false);
tbtn_timer.setChecked(false);
Toast.makeText(Smss.this, R.string.Toast_smss_wrongtime, Toast.LENGTH_LONG).show();
}
}
在上述代码中,调用了很多存储相应信息的方法,下面逐一介绍其意义。
messagePre():用于存储定时发送的短信息,用put方法将光标前字段和光标后字段分别存放到message_before与message_after变量中。代码为: //存储信息字段
public void messagePre(){
String string = etxt_message.getText().toString(); String cut_sString = string.substring(0,
etxt_message.getSelectionStart()); String end_sString = string.substring(
etxt_message.getSelectionStart(), etxt_message.length());
SharedPreferences pres =
getSharedPreferences("SmssPre",Context.MODE_PRIVATE); SharedPreferences.Editor ed = pres.edit(); ed.putString("message_before", cut_sString);//取得光标前字符串
39
青岛大学本科生毕业论文(设计) 方萌 ed.putString("message_after", end_sString);//取得光标后字符串
ed.commit();
}
setDateTime():存储日期和时间的方法,用户设定起初已经设定好了定时时间,并且存储在公共变量myear,mmonth,mday,mhour,mminute中,此方法就是将这些变量保存到表单,供用户查阅。代码如下:
public void setDateTime(){
SharedPreferences pres =
getSharedPreferences("SmssPre",Context.MODE_PRIVATE);
SharedPreferences.Editor ed = pres.edit();
ed.putInt("year", myear);
ed.putInt("month", mmonth);
ed.putInt("day", mday);
ed.putInt("hour", mhour);
ed.putInt("minute", mminute);
ed.commit();
}
updateContactPre():将联系人称谓和电话号码对应存储到表单中,用for
循环依次存储,这样存储不用担心称谓和电话号码的不一致: //存储所选联系人的数据
public void updateContactPre(){
if(tbtn_timer.isChecked()){//定时功能打开的时候才能存储
SharedPreferences pres =
getSharedPreferences("SmssPre",Context.MODE_PRIVATE);
SharedPreferences.Editor ed = pres.edit();
clearContactPre();
try{
ed.putInt("count",name.size());//记录所选联系人个数
if(tbtn_insert.isChecked()){//是否发送联系人称谓
ed.putBoolean("isinsert", true); //记录插入服务的状态
}else{
ed.putBoolean("isinsert", false);
}
ed.commit();
int count=pres.getInt("count", 0);
for(int i = 0;i"+pres.getString("message_after", "");
}else{
message=pres.getString("message_before",
"")+pres.getString("message_after", "");
}
etxt_messageback.setText(message);
}
startAlarmService():启动定时服务,前面已经介绍过,在此就不必赘述。
当发送定时短信后,系统界面的任务栏会提示一个消息和图表,这是用于提醒用户正在等待定时短信的发送。在本系统中,大多的后台服务都会建立一个任务栏图表,这样对用户更直观,管理手机更方便。这样的状态栏通知图表是调用SDK中的notificationManager来实现的,在此自定义了一个单独的公有类,用于在本程序中调用此类,节省代码量:
public static void makeNotify(int id,Context from,Class> to,int icon,
String tickerText,String title,String body){
notificationManager = (NotificationManager) from
.getSystemService(NOTIFICATION_SERVICE);// 获取系统服务(消息管理)
// 点击通知时转移内容
intent = new Intent(from, to);
// 设置点击通知时显示内容的类
pendIntent = PendingIntent.getActivity(from, 0, intent, 0);
notification = new Notification();
notification.icon = icon;// 设置在状态栏显示的图标
notification.tickerText = tickerText;//设置在状态栏显示的内容
// 设置通知显示的参数
notification.setLatestEventInfo(from,
title, body, pendIntent);
行通知. notificationManager.notify(id, notification);// 执
}
public static void cancelNotify(int id){
notificationManager.cancel(id);
}
41
青岛大学本科生毕业论文(设计) 方萌
public static void cancelAll(){
notificationManager.cancelAll();
}
}
实现结果如图4.15:
图4.15定时计划启动效果 4.3来电管家模块实现
此模块的界面设置是套用android专门用于建立设置界面的PreferenceScreen格式,首先将页面布局写在res/xml文件夹下,布局代码如下(列出结构,部分代码省略):
0){
//否则,值返回真
Log.d("mydebug", "finded");
cursor.moveToFirst();
cursor.close();
return true;
}else{
cursor.close();
46
青岛大学本科生毕业论文(设计) 方萌
return false;
}
}
这里还用到了一个方法isRecoming(),是用来判断是否是第二次来电或来短信。本模块中,若打开自动回复服务,对每个符合条件的来电号码,都只能回复一次,这是为了防止恶意电话或短信的骚扰而造成不必要的扣费。实现方法为声明一个字符串数组,将来电号码分别存放到数组中,当来电时,将来电号码与字符串数组中的字符号码进行对比,若相同说明是第二次来电或短信,返回false,否则返回true。代码如下:
//是否为已回复的号码
private boolean isRecoming(String phonenumber){
if(incoming_count>0){
for(int i=0;i
sensors=mSensorManager01.getSensorList(Sensor.TYPE_ORIENTATION);
mSensorManager01.registerListener(//注册手机角度感应
mSensorListener,
sensors.get(0),
SensorManager.SENSOR_DELAY_NORMAL);
Log.d("mydebug", "callreceiver");
}catch(Exception e){
}
break;
4.4手电筒模块实现
手电筒的实现较为简单,重点在于如何维持手机常亮和如何记忆和恢复之前的亮度。由于点击图标直接开启该功能,也就是要在onCreate中执行常亮操作。
首先定义要绑定锁定的对象为背景光:
/* 取得PowerManager */
49
青岛大学本科生毕业论文(设计) 方萌
mPowerManager = (PowerManager)
getSystemService(Context.POWER_SERVICE);
/* 取得WakeLock */
mWakeLock = mPowerManager.newWakeLock
(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "BackLight"
);
将背景光亮度调到最大:
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 1.0f;
getWindow().setAttributes(lp);
在此activity运行时,会触发onResume方法,在此方法中将手机的锁定功能唤醒即可使手机常亮:
/* 唤起WakeLock的method */
private void wakeLock()
{
if (!isLocked)
{
isLocked = true;
mWakeLock.acquire();
}
}
这样就实现了背景光的常亮,默认为白色,经测试白色光亮度最强。在程序被中断时会触发onPause方法,在此可以将背景光亮度恢复,这要求解除对背景光的锁定:
/* 释放WakeLock的method */
private void wakeUnlock()
{
if (isLocked)
{
mWakeLock.release();
isLocked = false;
}
}
为了实现背景光颜色可控,可在列表对话框AlertDialog的onClick事件中执行以下一句代码即可:
/* 更改背景颜色 */
mLinearLayout.setBackgroundResource(color[which]);
手电筒选择颜色的实现效果如图4.17:
50
青岛大学本科生毕业论文(设计) 方萌
图4.17选择手电筒的背景光颜色 4.5电蚊香模块实现
电蚊香主要靠播放音频来驱赶蚊虫,界面的实现很简单,服务的建立在之前
的模块中也有介绍。所以重点在于如何使系统后台服务播放音频。编译前先将音
频文件killmosall.mp3存放在res/raw文件夹中,播放语句如下:
/* 播放防蚊铃声 */
if(!myPlayer.isPlaying())
{
myPlayer.seekTo(0);
myPlayer.setLooping(true);
myPlayer.start();
}
当服务关闭时执行如下语句:
/* 关闭防蚊铃声 */
if(myPlayer.isPlaying())
{
myPlayer.setLooping(false);
myPlayer.pause();
}
此模块的实现效果如图4.18:
51
青岛大学本科生毕业论文(设计) 方萌
图4.18防蚊服务的开启(右)与关闭(左)
4.6开机启动程序的实现
之前所提到的广播都是在服务里注册的,这样是为了增加可控性,因为如果直接在注册文件中声明广播,开机则会自动运行,为避免资源的浪费,可在用户需要时注册建立。但要实现开机启动某项服务,需要在AndroidManifest.xml
文件中声明如下广播:
实现开机启动对此系统有很大的意义,可以保证手机重启后之前关闭的服务可以正常运行,不会因为重启而停止服务。以上定义的广播监听器专门监听开机动作,在广播监听器启动时读取启动项表单(AAPre.xml),根据里面的内容启动某项服务:
SharedPreferences pres =
context.getSharedPreferences(AAPRE,Context.MODE_PRIVATE);
if(pres.getBoolean("Smss_Timer", false)){
……
}
if(pres.getBoolean("Manager_Leave", false)){
Intent intent=new Intent(context,managerService.class);
52
青岛大学本科生毕业论文(设计) 方萌
context.startService(intent);
}
if(pres.getBoolean("Manager_Overturn", false)){
Intent intent=new
Intent(context,managerOverturnService.class);
context.startService(intent);
}
在每个服务启动或者关闭时都要调用如下方法,用来更新启动项表单: public void UpDateAAPre(String AppName,boolean status){ SharedPreferences pres =
getSharedPreferences("AAPre",Context.MODE_PRIVATE);
SharedPreferences.Editor ed = pres.edit();
ed.putBoolean(AppName, status);
ed.commit();
}
4.7系统展望
本系统在设计之初已经考虑到功能扩展的重要性,这种总分结构非常适合拓展新功能。由于时间紧迫和掌握知识的不足,之前设想过的很多功能没有实现,下面简单概括:
实现防盗功能,即只要手机中安装了此程序,就可以在换卡时进行短信的指定号码发送,还可以自定义打开GPS发送地理位置。这个模块没有实现的原因是工程量太大,时间太紧。
通话变声功能,在打电话时为了不想让对方知道自己的声音,可以对通话声音进行处理。这里用到比较底层的知识,由于初学android,此功能比较难实现。
远程控制功能,可以发短信到本手机进行相应的操作,如接收到一条特征短信用于打开录音设备。当然这些远程控制都需要进行密码设置。密码和特征码都正确才自动进行操作。
假来电功能,可以实现定时模仿来电。由于实用性不强,此模块暂且搁置。
系统联网检测升级功能,实用性较强,但没有服务器,不能立即投入使用。
短信群发功能的升级,模块中可增加对短信网站内容的检索,用户可以直接在程序中联网查询各种短信,可一键复制到编辑框中进行编辑和群发。查找联系人列表时应该更方便,提供更好的用户体验。
来电管家模块可增加呼叫转移等功能,增加黑名单白名单的过滤,增强系统安全性。
53
青岛大学本科生毕业论文(设计) 方萌
第五章 系统测试
5.1 测试的定义和目的
完成系统的编程后,测试工作是必不可少的后续步骤之一。只有通过测试,系统才能不断优化,使系统更稳定安全;只有通过测试,才能全面了解本系统的性能;只有通过测试,才能更好的掌握系统的运行机制,为以后的维护和升级提供前提和基础。总之,测试是为了发现软件中的错误而在尽可能多的情况下的软件执行过程。
5.2 测试的方法
因为手机种类多样,硬件和系统版本各有差异,而且手机经常有意外事件发生,如受突然断电,手机没有信号,手机屏幕大小不同等因素的影响,对软件的各种情况下运行结果也可能产生差异。因此本系统的测试分为横向测试和纵向测试,即不同系统版本中的测试和相同版本不同条件的测试。横向测试是在不同软硬件环境下如在不同系统版本,不同手机的CPU和内存等环境中进行安装运行;纵向测试则在同一机型的不同条件进行安装运行,如横屏,断电等。 5.3测试发现的问题及解决办法
5.3.1短信群发测试
在支持重力感应手机的测试中,若选择了联系人,然后将手机横屏,联系人列表就会消失,只是listview消失,实质的内容仍然存在,短信可以正常发送。
经过反复查阅,发现这个现象是因为屏幕改变后页面重新加载产生的。我们可以通过固定此页面的方向来解决此问题。实现方法为在注册文件中的相应activity中添加代码:android:screenOrientation=”landscape”。
定时短信服务在手机重启后失效,经反复测试,验证了AlarmManager不支持重启。所以定时服务没有开机启动能力,此功能待完善。
54
青岛大学本科生毕业论文(设计) 方萌
5.3.2来电管家测试
翻转静音功能在不同系统中的测试结果不同。2.1版的android系统中,手机的翻转角度为-120?时静音,而2.2版的android中只要超过-90?时就静音。究其原因可能是因为每个版本固件的参数不同造成的,或者此机型2.2固件中的感应器不完善。
5.3.3其他模块的测试
手电筒和电蚊香的原理及功能较为简单,暂时没有发现bug。在电蚊香试验中,发现驱蚊效果不明显,这有两方面的可能性,一是可能声音文件在每个播放器硬件里的频率有所差异,二是蚊虫在生物界的不断优胜劣汰的进化造成的。
55
青岛大学本科生毕业论文(设计) 方萌
第六章 总结
经过将近半年对Android的研究学习和编程实践,终于完成了此毕业设计。在学校里只学过JAVA的基础知识,对手机编程特别是Android编程从没接触过。本软件的设计灵感来源于自己的手机,自己对手机应用的需求激发了对设计制作该软件的兴趣和动力,也是因为现在Android系统如日中天,对于即将工作的我们,多学一点热门技术对于以后的就业也会有很大帮助。
当设计完成此软件之后,对软件工程专业又有了深刻的体会:编程就像盖楼房,要有框架,地基,一砖一瓦都不能马虎大意,否则极不稳定,若有风吹草动就会倒塌。经过反复的测试和使用,从一开始的构思,到实践,从处处bug到基本稳定,此软件在不断完善,个人的编程素养也得到了很大的进步。
当然,所有的系统并不是都完美,此系统也有很多不足之处,除了之前提到的定时重启失效和手机角度这样比较大的问题,还有许多细节问题,但不会影响系统的稳定运行,这些细节有:没有发送短信成功的真实反馈,没有判断电话格式正确与否的功能。相信通过日后不断的完善,此软件会更上一层楼。
56
青岛大学本科生毕业论文(设计) 方萌
谢 辞
论文写作期间,在张树美老师诲人不倦的指导下,我顺利的完成了毕业设计。在我不知道如何下笔的时候,在我不懂得写作方法的时候,张老师殷勤的指导让我醍醐灌顶,茅塞顿开,可以说,没有张老师的帮助,我的毕业论文也不会如此顺利的完成。在这里首先对张老师表示深深的谢意。
其次,感谢老师和同学和一切对我的关心和帮助的人们,在我写作期间,各位老师和同学积极帮我查阅资料,帮忙测试软件,提出建议,舍友们为我提供的安静祥和的学习氛围,那是一种家的感觉,这些都给我的软件设计和毕业论文带来了很大的帮助,再次感谢你们。另外还要感谢青岛大学网和图书馆给了我一个自我学习的良好环境。
最后,也是最重要的,就是要感谢这四年来教过我的老师们,是他们给了我良好的专业知识,是他们让我有了充实的大学的学习生活,这也为毕业设计积累了扎实的基础。
57
青岛大学本科生毕业论文(设计) 方萌
参考文献
1.公磊 周聪,《基于Android的移动终端应用程序开发与研究》,计算机与现代化,2008(8)年, P4-34
2.高焕堂,《Android应用框架原理与程式设计36技》 Google公司,2008年 3.马越,《Android的架构与应用》,中国地质大学(北京)硕士学位论文,2008年P25-102
4. 印旻《Java与面向对象程序设计教程》清华大学出版社,1999年,26-56 5. Herbert Schildt,《Java2实用教程》,北京:清华大学出版社,2004,1,
P45-74
6. 张跃平 王克宏《JAVA2实用教程》,北京:清华大学出版社,2001,10,P47-76 7(贝利,《数据结构Java语言描述》,北京:清华大学出版社,2004.9,P66-76 8. 梅尔,《Android2高级编程(第2版)》,清华大学出版社2010年,P40-76 9. 盖索林,王世江,《Google Android开发入门指南(第2版)》,人民邮电出版社,2009年,40-76
10. 墨菲,《Android开发入门教程》,人民邮电出版社,2010年,P15-86 11. 韩超 梁泉,《Android系统原理及开发要点详解》,电子工业出版社,2010年,P40-76
12. 汪永松,《Android平台开发之旅》,机械工业出版社 2010年,P40-215 13. 余志龙 等,《Google Android SDK开发范例大全(第2版)》,人民邮电出版社,2010年,P4-239
14.张桂元,贾燕枫,《Eclipse开发入门与项目实践》,人民邮电出版,2006年, P36-78
15.史济民,《软件工程――原理、方法与应用》,高等教育出版社,2002年, P45-345
58