2023年12月16日发(作者:戚冉冉)
.
摘要
近年来,智能手机的功能日趋强大,移动终端应用程序层出不穷。由于现在人们的工作繁忙,手机的丢失似乎也成为常有的事。与之带来最让人烦心的是私人数据的丢失及带来的不安全隐患。基于以上原因,本文设计了一款手机防盗追踪软件。本软件利用
Android系统的广播机制,当手机用户开启防盗追踪功能后,本程序将后台监听手机开机启动、信号状态、短信收发以及位置的改变,通过监听手机用户 SIM 卡的 IMSI码的改变来判断手机安全状态,监听并截获安全短信内容,实现非法用户的手机号码向合法用户预先设置的安全号码发送特殊信息的功能,告知用户当前手机状态和位置信息,并可通过安全短信控制被盗手机锁屏、销毁隐私数据、发报警音等功能。最后将设计完成的软件进行测试,其所有功能都完美实现,真正起到了手机防盗追踪的作用。
关键词:Android系统 手机防盗 广播机制 监听器1 / 77
.
ABSTRACT
In recent years, the intelligent mobile phone function is powerful, the mobile terminal
application emerge in an endless stream. Because now people's busy work, the lost mobile
phone also seems to be a common thing. And bring the most disturbing is a private data loss
and insecurity hidden trouble. Based on the above reasons, this paper introduces the design of
a mobile phone anti-theft tracking software. This software uses Android system broadcast
mechanism, when the mobile phone users to open anti-theft tracking function, the program
will monitor the background mobile phone boot, signal condition, send and receive text
messages and a change of location, through the monitoring mobile phone user SIM card IMSI
code changes to determine mobile phone safety state, monitor and intercepts a secure message
content, realize the illegal user the mobile phone number to the legitimate user preset safety
numbers to send special message to inform the user of mobile phone function, current status
and location information, and through SMS security control of stolen mobile phone lock
screen, the destruction of privacy data, send alarm sound and other functions. Finally
completed the design of the software testing, all of its functions are perfect, played a real
mobile phone anti-theft tracking function.
Keywords: Android system DroidRing Broadcasting mechanism Listener
目录
1绪论1
1.1应用开发研究背景与意义1
1.2国内外研究现状1
国内研究状况1
国外研究状况2
1.3开发研究内容2
2手机防盗应用开发的基础2
2.1Java基础2
2.2Android基础3
3手机防盗应用方案的设计3
3.1UI设计4
3.1.1 UI窗口层5
3.1.2 UI主层5
3.1.3 UI功能体验层5
3.1.4 UI指令查看层6
3.1.5 UI信息设置层6
3.2Function设计6
应用初始化6
1 / 77
.
功能选择7
功能体验7
功能查看7
功能设置7
3.3Service设计8
数据库存储服务8
监听按钮事件服务8
开机启动和短信广播服务8
GPS服务9
私人数据的管理9
4手机防盗应用方案的实施9
4.1UI的实现9
Activity9
ListActivity12
PreferenceActivity14
Dialog15
4.2由Sever支持的Function实现16
广播机制服务16
换卡短信通知17
定位手机18
数据销毁19
锁定手机20
发报警音21
数据库存储应用21
5手机防盗应用测试22
5.1防盗应用初始化22
5.2手机定位功能测试22
5.3换卡短信通知功能测试22
5.4锁屏功能测试22
5.5销毁数据23
5.6发报警音23
6手机防盗应用说明23
结论23
致谢24
参考文献25
附录一26
附录二26
附录三27
2 / 77
.
1 绪论
1.1 应用开发研究背景与意义
随着 3G 技术的不断发展,手机移动应用开发成为目前热门的技术之一。种类繁多的手机应用以及先进的硬件,使得手机已经不完全是用来通话的工具了,它巧妙的融合了PDA
关于手机我们能想到很多人们担心的话题。而最为愁人的就是现在的手机大都兼容各种卡,一旦丢失,就会机卡两空。在我们忙碌的工作生活中,似乎手机丢失已经成为了一种自然的事情。其实不论你的手机值不值钱,丢东西的事情本身就会让人头疼。那么该怎样制服盗机者,在我们提高自身防范意识的同时,适当的为手机增加些防盗功能也是应该的。
在众多手机操作系统中,Android手机操作系统由于他的完全开放性使得其应用人群独占鳌头。
图1.1 Android系统构架
Android〔智能机器人是 Google 开发的基于 Linux 平台的开源手机操作系统,该平台由操作系统、中间件、用户界面和应用软件组成,其系统构架如图1.1所示,被誉为第一个完整、开发而免费的移动平台。Google 提供在线文档、工具、论坛和软件开发工具包等资源,以便开发者在 Android 平台上开发应用程序。并且众多手机制造商,如三星、摩托罗拉、HTC、LG和小米等,还有许多半导体公司,如英特尔、XX仪器、NVIDIA
和高通等,参与 Android 手机设计。由此可见,Android发展前景不容小觑,已成为目前主流的手机操作系统之一。Android 手机设备运行在 Linux 操作系统下,这使得其上运行的 Android 应用程序具有很强的安全性。每一个 Android 应用程序均运行在不同的进程中,每个进程都对应一个 Dalvik 虚拟机的实例。基于 Java 虚拟机,Dalvik 为移动设备进行了优化设计。Dalvik 虚拟机具有较小的内存占用,而且多个 Dalvik 虚拟机的实例在手机设备中可以并发运行。Android 应用程序为托管代码,所以,由应用程序而导致系统崩溃的可能性很小,这也降低了设备崩溃的可能性[2]。
综观Android手机系统,我们不难发现,应用本系统开发手机的生产厂商多,用户基数大,安全性高,并受到众多大牌公司支持,基于以上优越性,在Android系统上开发本手机防盗应用具有重要的现实意义。
1.2 国内外研究现状
1.2.1 国内研究状况
毋庸置疑手机防盗应用肯定归属于手机安全类软件,对于安全软件的开发与研究又是杀毒软件公司首要考虑的功能之一,所以国内的很多杀毒软件公司在自己的产品中都涉及了防盗功能。例如金山手机卫士、360手机卫士、QQ手机管家等保护手机系统安全类软件中具有防盗功能。
1 / 77
.
图 1.1手机防盗
1.2.2 国外研究状况
英国一家手机服务公司宣布推出一整套手机防盗软件的服务,使用该服务的用户在手机被盗后不仅可及时转移手机信息,手机还能发出刺耳鸣声,让窃贼根本无法使用所盗手机。当用户在手机中安装这款软件后,每月只需支付10英镑〔约合18美元即可享受防盗服务。一旦手机被盗,用户可立即致电公司。公司随即向被盗手机发送指令,将里面存储的信息全部转移至安全服务器,随后锁定手机功能并使手机发出刺耳的鸣声。
该公司介绍说,防盗程序启动后,窃贼即便更换SIM卡也无法解除锁定。此外,只要不取出电池,鸣声就不会停止。用户购买新手机后,还可申请将原来手机中的全部信息转移至新手机内。据伦敦市警察局统计,该市每月约有1万部手机被盗。警方希望这一手机防盗软件能改善这一局面[3]。
美国的苹果公司,在其官网上向所有用户提供了一项云端技术服务,只要苹果手机或者苹果的其他移动设备,都可以享受到手机卫星定位功能。具体做法是:首先,在拿到苹果后,你要先申请属于你的Apple ID,登录苹果商店或者在Mobile Me上注册,这个应用就可以实时定位你的iPhone的位置。
图 1.2 苹果手机防盗
1.3 开发研究内容
从上面的应用我们可以看出,无论是国内还是国外,只要是致力于防盗功能的软件,其最核心功能都用到了GPS、锁屏、媒体播放等。因此,综合以上各软件优点,新型的手机防盗应用软件应具有GPS定位、被盗时锁屏、通过短信控制以最大音量发报警音、远程销毁隐私数据以及偷拍盗窃者长相等功能。同时,防盗应用软件也应充分利用操作系统固有的资源。
因此,本课题的任务是设计一款基于 Android 平台开发的一款手机防盗软件。通过Android系统中的广播机制后台监听手机的各种状态,根据状态的改变来判断手机是否安全。一旦手机丢失,我们便可通过向失窃手机发送指令短信的方式,应用Android系统的GPS
2 手机防盗应用开发的基础
2.1 Java基础
Java由Sun
.
[4]。Java语言具有极强的跨平台能力,多语言的支持,占据着互联网开发语言的首位。
基于Android系统的手机应用全部应用Java语言编写完成。所以,想在Android系统上做出一个好的应用来不仅要会Java语言,而且还要运用熟练。对此,我通过观看Mars老师的Java4Android视频和对Java相关书籍的精读与练习,强化了自己对Java语言的掌握,使我对Java的运用能力有了很大的提高,并为编写与设计Android应用奠定了良好地基础。
2.2 Android基础
知己知彼者百战百胜。想在Android系统上做开发,就一定要了解Android系统,知道他的由来和内部构造。
Android操作系统最初主要支持手机,20XXGoogle收购了刚刚成立22个月的Android公司,也正是有了在Google这样巨头公司下发展的机会才使得Android系统迅猛发展。20XX11月5日,以Google为首的34家公司宣布成立OHA
最早的Android版本为Android 1.0〔发条机器人,自Android系统发布第一版本到现在已经更新多次。Android1.1Beta〔阿童木 20XX9月发布的Android第一版,后来由于涉及到版权问题,Goolge将其命名规则变更为用甜点作为它们系统版本的代号的命名方法。其各版本logo如图2.1所示。
Android 1.5 Cupcake〔纸杯蛋糕
Android 1.6Donut〔甜甜圈
AndroidEclair〔松饼
Froyo〔冻酸奶
Android 2.3Gingerbread〔姜饼
Android 3.0Honeycomb〔蜂巢
Android 3.1Honeycomb〔蜂巢
Android 3.2Honeycomb〔蜂巢
图 2.1 Android版本
Android 4.0 Ice Cream Sandwich〔冰激凌XX治
Android 5.0Jelly Bean〔果冻豆
3 手机防盗应用方案的设计
在电子领域,要想拥有很好的市场前景,就必须应用最先进的设计技术、最成熟的设计理念以及最合理的设计方法才能使得产品得以发展。于是我选择了目前市场应用最为广泛的金山手机卫士、360手机卫士和QQ手机管家其中的手机防盗部分作为参考。学习并对比这3家在此功能上的不同。分别在UI
表格 1 手机防盗UI、Function和Service对比
比对参数 金山手机防盗 360手机防盗 QQ手机防盗
3 / 77
.
3步 3步 4步
6个 6个 5个
UI
以文字为主 视图+文字 以文字为主
灰色 白色 白色
换卡短信通知 换卡短信通知 数据删除
销毁数据 删除数据 手机定位
定位手机 追踪手机位置 找回密码
主要功能
发报警音 响报警音 远程锁机
Function
锁定手机 锁定手机
防盗拍照
输入错误提示 一般 精准 一般
GPS定位功能 有 有 有
Service 短信监听发送 有 有 有
开机监听 有 有 无
从表格1中我们可以很清楚的看到,在UI方面360更为注重,以多图少字的方式展现功能,使用户更加喜欢,也方便了用户对功能的理解。不过从Function上来看,金山手机防盗的设计就要优于另外两家,在所有功能的基础上还加进了一项防盗拍照,这是仅有4项功能的QQ所没能想到的安全设计。
综合以上软件优点便是此软件将要实现并达到的目标。因此我将结合360的UI、金山的Function和Service做出一款即看上去漂亮而且功能也强大的手机防盗软件。
初始化设置步骤
主界面信息栏个数
进入应用层界面效果
UI层底色
3.1 UI设计
UI设计是指对软件的人机交互、操作逻辑、界面美观的整体设计。好的UI设计不仅是让软件变得有个性有品味,还要让软件的操作变得舒适、简单、自由,充分体现软件的定位和特点。如图3.1就是一副很美观的UI。
图 3.1UI
软件设计可分为两个部分:编码设计与UI设计。编码设计大家都很熟悉,但是UI设计还是一个很陌生的词,即使一些专门从事网站与多媒体设计的人也不完全理解UI的意思。UI的本意是用户界面,是英文User和 Interface的缩写。从字面上看是用户与界面2个组成部分,但实际上还包括用户与界面之间的交互关系。
在飞速发展的电子产品中,界面设计工作一点点的被重视起来。做界面设计的"美工"也随之被称之为"UI设计师"或"UI工程师"。其实软件界面设计就像工业产品中的工业造型设计一样,是产品的重要卖点。一个电子产品拥有美观的界面会给人带来舒适的视觉享受,拉近人与商品的距离,为商家创造卖点。界面设计不是单纯的美术绘画,他需要定位使用者、使用环境、使用方式并且为最终用户而设计,是建立在科学性之上的艺术设计[6]。
综合上述UI设计特点,加上方便实用的设计特点,我将本手机防盗应用的UI分为了5层,他们由UI窗口层、UI主层、UI功能体验层、UI功能查看层和UI功能设置层组成。其层次流程如图3.2所示。
图 3.2 UI总流程图
4 / 77
.
3.1.1 UI窗口层
UI窗口层分为两个界面,一个是初次开启应用时进入的设置初始化界面,另一个则是用户在非第一次开启应用时弹出的用户身份验证窗口。
图 3.3 初始化设置
当用户第一次开启应用时,展现在用户眼前的是一个设置初始化界面,如图3.3所示。用户可按照相应提示完成放到设置,其中包括设置防盗安全密码和设置安全号码。防盗安全密码将用于验证应用本软件用户的身份,在非第一次开启此防盗软件时将需要用户输入防盗安全密码。另外,设置好的防盗安全密码将会编进防盗指令,用于控制手机实现相应的操作。安全手机号的设置非常重要,设置成功后,此号码将被认为是唯一可信赖的手机号码,当手机被盗后,防盗软件将会按照指令向安全号码手机发送手机状态。
图 3.4 验证窗口
图3.4展现的是用户在非首次开启应用时弹出的验证用户信息窗口。此通行密码为用户设置的防盗安全密码,通过此方式保证了用户设置信息的安全性。
UI窗口层为本应用软件的最顶层,此层的UI设计好坏决定了用户对本软件的第一印象,所以要想得到用户的肯定,这层的设计一定要做好。为此,在选择文字的字体、颜色、大小以及摆放位置做了无数次的调整,努力达到最好、最舒适。除了这些我还在输入文本框里加进了提示信息如:输入密码框里的"6~12位数字或字母"等,在方便用户应用的同时也美化了UI。
3.1.2 UI主层
UI主层是个选择界面如图3.5,本层为用户提供3种主要操作,分别为防盗功能体验、防盗指令查看、防盗信息设置。
图 3.5 UI主层
在本层UI的上面是一个宇宙图片,寓意着安装本应用后,即使你的手机被带到了宇宙我们也能找到它,当然这有些夸张了,不过我们还是要对此软件充满信任的。
除了这张宇宙图片我还在每个选项前后都加附上了相应功能的logo,学习360的多图设计,用视觉告诉用户本条选项的功能。
为达到UI布局整齐的效果,我采用列表式布局,将选项按照用户需求量进行排布,这样的布局可是UI实现整齐、清晰、功能突出等效果,属于理想的UI设计。
3.1.3 UI功能体验层
UI功能体验层如图3.6所示,此UI界面同样继承优良设计布局方案将本应用所有功能统一以列表形式列出,最前端图标代表着此条选项所要实现的功能,然后每个选项的功能说明以大字功能名加小子简要说明的形式整齐的展现在界面上,让用户对选项功能一目了然。
图 3.6 UI功能体验层
当用户点击进入UI功能体验层的每个选项后,就会看到每个功能实现的具体说明,而且在每个可以单机实验的功能里都加进了功能体验按钮,可以让用户体验本功能的真5 / 77
.
实效果。其效果图见附录一。
3.1.4 UI指令查看层
在UI指令查看层,总结罗列了开启每个防盗功能的防盗指令,用户可以在这里方便快捷的得到所需防盗指令,如图3.7所示。
图 3.7 UI指令查看层
3.1.5 UI信息设置层
UI的设置层是UI非常重要的一个视图层,此层要以最方便,最简约,最快捷为核心排版设计,而且要尽量覆盖本软件的所有功能设置。基于以上要点,首先总结本防盗软件的设置功能如表2。
表格 2设置功能
所需功能 功能目的 功能体现设置此功能键的意义
形式
防盗开关 方便控制防盗功能开关按钮 可以方便用户对防盗应用软件的控制,无的开启与关闭 需卸载就能关闭防盗
换卡锁定避免因用户自己换开关按钮 在避免发送错误指令的同时,用户也可通开关 卡执行错误指令 过此开关对锁定功能进行单独体验
换卡短信避免因用户自己换开关按钮 在避免发送错误指令的同时,用户也可通通知开关 卡执行错误指令 过此开关对换卡短信通知功能进行单独体验
防盗密码用于修改安全密码 加密形式 方便用户在首次初始化后改变防盗安全重置 密码
安全手机用于修改安全手机显示预置方便用户在首次初始化后改变防盗安全号重置 号码 号码 手机
按照表格2中的功能需求,我在设置UI里建立了与之相应的5个控件,以方便用户对软件的应用控制。最终设计出图3.8的效果来实现功能。
图 3.8 UI设置层
3.2 Function设计
我们在UI的设计中了解到一款软件拥有一个美观的UI是多么重要,那我们该如何实现这种华丽的显示呢?这就需要又一个很好的后台设计既功能设计。
3.2.1 应用初始化
初始化界面是让用户设置信息用的,所以首先我要告诉用户需要设置的信息都有哪些,介绍完后还要在相应的位置给出用于填写信息的控件。
6 / 77
.
这里我们用Android中最常用的TextView和EditText两个布局控件满足需求。并且在EditText里加入hint属性显示相关提示信息。对于密码的设置,我们都希望处于不可见状态以保证我们个人信息的安全,我用password属性来控制输入时的显示状态。在整个UI的最下面我还放置了两个按钮,方便用户的进一步应用和退出,此功能将用Button控件实现。
3.2.2 功能选择
功能选择的UI主要分为两部分,可以从上到下分为两段,在布局控件中用LinearLayout实现,并设置排版属性为垂直布局。上半部为一个图片,下面则需要一个List控件完成效果,整个UI的程序将用继承ListActivity类来描述已达到选项罗列的效果[7]。
图3.9为Android的文件管理。在Android中所有资源文件要统一管理并放到res文件夹中,并把每个资源都加上各自的ID,以方便调用。所有的调用ID则会放到gen文件夹下的文件中进行统一遍历,我们所要的资源便可从这里索取。例如我们的宇宙图片。
图 3.9 文件管理
3.2.3 功能体验
功能体验UI分为两层呈现。外面一层同样用一个继承ListActivity的类来实现,在list空间里排布好每个图标和文字的位置,这里要用到ImageView控件添加图片。内层则是一个介绍体验层,这层的总体排布用LinearLayout的垂直分布就可以完成。添加Button按钮实现用户体验功能。
3.2.4 功能查看
这个界面完全是文字的排布,同样用ListActivity加以LinearLayout垂直型布局就可以完成。
3.2.5 功能设置
功能设置UI为用户可操控界面,所以要使用继承PreferenceActivity的类来完成相应的功能,此类是Android专门用来做UI设置界面用的,所以这个类中方法的应用也相对方便,但其布局文件与众不同,需要在res文件中新建个XML文件进行单独管理。其布局空间类型主要分为3大类AppWidget Provider、PreferenceScreen和Searchable,其中最常用的是PreferenceScreen,在这里又包含CheckBoxPreference、EditTextRreference、ListPreference、Preference、RreferenceCategory、PreferenceScreen和RingtonePreference7个控件[8]。我们的UI设置界面就用PreferenceScreen来完成。
7 / 77
.
3.3 Service设计
手机防盗应用软件在实际应用过程中一定是常驻后台的软件,所以不管用户是否打开软件,只要是开启了防盗功能,那此软件就会一直在后台运行,出于这样的考虑,我们就必须引进一个强大的后台支持,那就是Service既后台服务。
3.3.1 数据库存储服务
在Android系统中,用于保存数据有3种方式:SQLite、SharedPreferences和File。
SQLite是一种嵌入式系统中很常见的数据库,而且所有的数据都储存在一个文件中,便于迁移。SQLite有见解的SQL访问界面、相当快的速度,而且仅占用相对其他数据库少量的内存空间。在Android平台上,SQLite库可以用来存储应用程序中使用到的数据,还可以通过定义Content Provider等方式,来让其他应用程序也可以取用其中的数据[9]。
SharedPreferences是以键值对来存储应用程序的配置信息的一种方式,它只能存储基本数据类型。一个程序的配置文件仅可以在本应用程序中使用,或者说只能在同一个包内使用,不能在不同的包之间使用。实际上sharedPreferences是采用了XML格式将数据存储到设备中,在DDMS中的File Explorer中的/data/data//shares_prefs下。
File是一种文件存储方式也是一种较常用的方法,在Android中读取/写入文件的方法,与Java中实现I/O的程序是完全一样的,提供了openFileInput<>和openFileOutput<>方法来读取设备上的文件。
具体问题具体分心,根据我们的需要与要求,本程序最终选定用SharedPreferences来存储我们的数据。我们将用户设置的安全密码、安全手机号、防盗功能开关状态、SIM卡的IMSI码等信息以键值对的形式存入其中进行保存。一个Value对应一个Key值,如图3.10所示,Key值便是我们所保存的数据信息,这样的保存方式既快捷又准确。
图 3.10 数据库存储方式
3.3.2 监听按钮事件服务
监听器是Android设计的一种监听模式,当用户执行了某些动作时,需要系统对这些动作做出相应的反应,那么这时就需要监听器来捕获这些来自用户的信息,将其传递给系统再做处理。
在我们的软件中将会运用大量的监听器,其中包括监听用户点击按钮事件、监听开机广播事件、监听短信广播事件等。
监听按钮事件,是将每个按钮绑定上一个监听器,用lickListener<>方法来实现,当触发相应的监听器后我们就可以执行我们想要的操作了。
3.3.3 开机启动和短信广播服务
防盗应用开启后会在第一时间对手机的SIM卡进行检查,判断时候更换。那么这种监听开机需要另一项Android机制的支持来完成——广播机制。
8 / 77
.
在 Android 里面有各种各样的广播,比如电池的使用状态,的接收和短信的接收都会产生一个广播。图3.11就是一张广播的运行机制原理图。
图 3.11 Android广播机制
各种广播在Android 系统中运行,当系统/应用程序运行时便会向 Android 注册各种广播,Android 接收到广播会便会判断哪种广播需要哪种事件,然后向不同需要事件的应用程序注册事件,不同的广播可能处理不同的事件也可能处理相同的广播事件,这时就需要Android 系统为我们做筛选。
本软件就利用开机广播和短信接收广播来判断手机状态和控制手机。
3.3.4 GPS服务
对于GPS我想大家现在都很了解,至少不会陌生,一般情况下每个装载GPS的设备都会由3颗卫星进行定位,在需要时可将设备所在的位置信息发送到GPS上,例如返回的经纬度,有了这些位置信息我们便可进行需要的操作[10]。
在本应用中将会运用Android手机的GPS定位系统,为我们获取手机的当前位置,便于用户找回丢失的手机
3.3.5 私人数据的管理
当用户的手机丢失后恐怕最担心的就是自己私人信息的外露,出于此考虑,本软件将通过继承IntentService的类,对用户的通讯录、媒体图片进行备份并向安全手机发送,同时将原有数据删除,以防止不法分子的非法企图。
4 手机防盗应用方案的实施
按照手机防盗应用技术的设计理念,我将从UI入手,在做完界面的基础上组合、衔接并加入相应的功能,最后通过Service实现后台监听、储存、处理等功能。
在实现这些功能之前我们需要先搭建Android开发环境,其具体操作流程见附表二。
4.1 UI的实现
在Android系统中,UI的构建主要都由Activity类来完成。为了开发方便,Android又构造了多个继承Activity类的子类。其中在我们的软件里用到了ListActivity和PreferenceActivity两个子类和Activity本身。
4.1.1 Activity
要使用Activity以及其子类首先要知道Activity的生命周期,只有知道其生命周期的顺序才能控制好界面的显示。图4.1为Google官方给出的Activity生命周期流程图。
9 / 77
.
图 4.1 Activity生命周期
在本软件中有8个UI直接通过继承Activity类构成,他们的应用方法XX小异,我就拿其中最复杂的初始化界面来介绍。
初始化界面的整体设计流程图如图4.2所示。
图 4.2 初始化UI流程图
➢ .java文件:
首先新建一个继承Activity的类First
Public class First extends Activity{}
在此类里面对UI界面进行编辑
以下为关键代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//覆写onCreate方法
public void onCreate
//绘制UI界面
setContentView<>;
//用findViewById的方法声明并得到Button控件
Button bt_sure =
//用setOnClickListener方法绑定Button监听器,获取用户点击按钮事件
bt_lickListener
//用if……else if……else if语句对用户设置信息进行判断
if
//用xt<>方法做出相应提示
xt<, "密码不能为空", _LONG>.show<>;
else if……
else{
//建立数据库编辑对象
Editor editor = <>;
//储存安全密码到数据库
ing<"password", Str_password1>;
//提交改动到数据库并保存
editormit<>;
//创建intent对象
Intent intent = new Intent<>;
//指明跳转Activity
ss<, >;
//开启要跳转的UI
ctivity
图 4.3 layout布局控件示意图
➢ 文件:
为Activity提供布局支持的layout文件是UI如何显示的控制中心,这个文件里的控件属性决定了控件的显示位置,图4.3是为First提供布局控件的layout的示意图,其主要代码如下:
10 / 77
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//第一行定义了布局文件所链接数据库的版本以及支持的语言,"utf-8"为中文。
//采用LinearLayout绝对布局的orientation属性定为vertical既垂直布局,第//一行属性为Android固定格式,我们不用过多研究
android:orientation="vertical" > //在布局文件中放进文本框并定义相关属性 //嵌套绝对布局的水平布局
//嵌套相对布局
➢ 文件:
Android中设立了一个统一管理文件,这个文件可以理解为Android的一个注册表文件,在这个文件中,我们可以声明我们自己定义的权限。如果所用的组件需要权限但没有在这个文件注册,应用程序就会无法正常运行。任何一个Activity类都是需要注册的,所以本应用的 主要代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//注册接受开机广播权限
//注册发送短信权限
//注册获取具体地址权限
/> //请求Activity显示 android:icon="drawable/dun" android:label="string/fangdao" > android:name=".Main" android:label="string/fangdao" android:clearTaskOnLaunch="true" > //通过intent-filter设置首显Activity 11 / 77 . 22 23 24 25 26 27 28 29 30 31 32 33 34 //注册广播接受类 android:name="_COMPLETED"> //注册服务类 4.1.2 ListActivity ListActivity 直接继承于Activity,是手机基本应用中最常用的一类应用程序。ListActivity用来在屏幕中显示一个列表,当点击其中的某一列时,可以触发一些操作。我们通过设置一个onListItemClick函数,来得到用户正选择了哪一列的信息,并做后续处理。使用了ListActivity类后,如果整个屏幕上只需显示一个列表,我们甚至可以把setContentView一行注释掉,不用定义列表的XML说明文件。因为ListActivity类已经默认绑定了一个ListView〔列表视图界面组件。图4.4就是一个典型的ListView示意图。 图 4.4 ListView示意图 在本软件中,UI主层和UI功能体验层的列表视图就是通过直接继承ListActivity这个类得到的。在继承ListActivity的类中要想显示列表内容就必须要调用setListAdapter 图 4.5 体验功能UI流程图 ➢ Java文件: 1 2 3 4 5 6 7 8 //首先我们的体验层要继承ListActivity public class Tiyan extends ListActivity //在这里设置各功能对应的数值 private static final int dingwei = 0; //定位手机 private static final int xiaohui = 1; //销毁数据 private static final int suoding = 2; //锁定手机 private static final int baojing = 3; //发报警音 private static final int huanka = 4; //换卡短信通知 12 / 77 . 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 //这里我们需要在layout文件中设置两个布局文件,一个用于主框架,另一个是为//list单独建立的,专门摆放list中的控件,下面这句代码就是主框架 setContentView<>; //建立一个HashMap放进 ArrayList中 ArrayList =new ArrayList //分别生成对象,以map1为例,后面4组方法相同 HashMap //向Map中对应位置装入数据, <"tiyan", "定位手机">; <"jianjie", "获取手机当前位置,便于您找回">; <"img", i>; //将Map加入list,这样数据就存放在列表当中啦 //生成Adapter,并实现通过setListAdapter<>方法实现list SimpleAdapter listAdapter = new SimpleAdapter new String[]{"tiyan","jianjie","img"}, new int[]{,,}>; setListAdapter //覆写onListItemClick<>方法获得用户点击事件 Override protected void onListItemClick // TODO Auto-generated method stub ItemClick Intent intent = new Intent<>; // ra<"textIntent","123">; //"防盗功能体验"界面 if { ss<,>; ctivity } else if<> …… } 图 4.6 ListActivity中layout框架 ➢ 文件: 图4.6展示了在ListActivity中两个layout的布局框架,以下为代码分析: ➢ 文件: 在文件中只有一个ListView控件 1 2 13 / 77 . 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //这里注意ListView的id一定为list,这是android系统中默认的id,不能自拟。 android:id="+id/android:list" // scrollbars属性为选择滚动条方向,这里我们定位垂直方向。 android:scrollbars="vertical" /> ➢ 文件: 在文件中采用相对布局RelativeLayout,以方便控件的摆放 // ImageView为图片View,是用于添加图片的控件 //一下是两个文本信息,就是实际列表中要显示的值 4.1.3 PreferenceActivity 在Android中有一个Preference类,用于手机的属性设置。因此当我们在界面上做设置的时候自然就会想到Activity+Preference的组合,前者用于界面的构造,后者用于设置数据的存放。不过虽然做法没错,但是会比较繁琐,因为每个设置选项都要建立与其对应的Preference。当然Android的设计者也考虑到了这点,在系统中为我们提供了一个专门用于开发界面设置的类PreferenceActivity,这个类完美结合了Activity与Preference,很大程度的方便了我们的开发,因此我们的UI功能设置界面就是通过继承此类的类来实现。 继承PreferenceActivity的UI设置界面的java文件无需过多的编程代码,因为在PreferenceActivity上做的任何设置,系统都会自动以键值对的方式储存到数据库里,当我们需要这些数据的时候,便可以直接从数据库里调用。所以我们只需要在布局文件中按需求添加控件就可以了。 PreferenceActivity的布局文件有些特殊,需要在res文件夹下新建一个xml文件夹用于单独存放此类控件和布局属性,如图4.7所示。 图 4.7 Preference的布局文件 其文件构架如图4.8所示。 图 4.8 文件构架 控件属性在本软件中的应用如图4.9所示。 图 4.9 文件属性构架 其代码就是对属性进行相应配置即可如android:password="true"等,这里就不做详细介绍了,具体代码请看附录二。 14 / 77 . 4.1.4 Dialog Dialog是android开发过程中最常用到的组件之一,它包括以下几种类型: 1. 警告对话框:Alertialog 2. 进度对话框:ProgressDialog 3. 日期选择对话框:DatePickerDialog 4. 时间选择对话框:TimePickerDialog 5. 自定义对话框:从Dialog继承 Dialog的创建方式有两种: 一是直接new一个Dialog对象,然后调用Dialog对象的show和dismiss方法来控制对话框的显示和隐藏。 二是在Activity的onCreateDialog 区别在于通过第二种方式创建的对话框会继承Activity的属性,比如获得Activity的menu事件等。 本软件就采用第二种方法用于显示弹出的对话框。其程序流程图如图4.10所示。 图 4.10 Dialog流程图 ➢ java文件关键代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 //首先先创建一个Dialog函数 private void putPWDialog<> { //渲染布局文件 LayoutInflater inflater = View view = e //生成Dialog对象并进行设置 r builder = new r le<"输入密码">; //显示Dialog界面 w showputPWDialog = <>; <>; //监听确定按钮 btn_lickListener //信息核对提示 if<<>.equals<"">> { else if<<>.equals else{} //监听退出按钮 btn_lickListener //完全退出程序 public void onClick tance<>.exit<>; } 15 / 77 . 经过大量的调整、核对以及调试,我们的UI界面就这样完成啦。到此为止把我们的软件安装到手机上就可以进行所有界面的切换了。 4.2 由Sever支持的Function实现 有了完整的UI,我们就可以在Function里实现这些UI对应的功能。对于任何一个软件来说,无论它有什么样的UI,人们最终想要获得的还是软件的功能。所以,只有Function的完美实现才能体现出一个软件的真正价值。 4.2.1 广播机制服务 之前已经介绍了Android系统中广播机制的概念,这里就主要说明在本软件中所用到的3种广播——开机完成广播、服务状态广播和短信接收广播。 开机完成广播和服务状态广播用于监测SIM卡的状态改变。当用户开机完成时,系统就会向接收开机完成广播的应用软件发送开机完成广播,告诉他们已完成开机动作,此时软件就可以在接收此指令后做出自己需要的动作,例如开机运行的软件就都需要接收开机完成广播。服务状态广播也是同样的原理,当手机检测到信号后就会由系统向所有应用发送服务状态改变的广播。 短信接收广播是当手机接收到短信时Android系统向应用程序发送的一种广播。手机系统中自带的有些功能都要通过这种广播来完成动作。例如手机收到短信时会产生音乐和振动等状态,这就是由短息模块在接收到系统短信接收广播后作出的动作。 为了接收来自系统的广播,Android为开发者提供了一个专门用于接收广播的类既BroadcastReceiver类,本软件就通过继承此类实现接收所有广播。在Android中光有接收的类还不行,要想让系统把广播发送到你的应用程序还必须在文件中进行权限注册,让系统知道你需要接收广播并给你开放ROOT允许你使用才行。下面代码为本应用所有的权限注册代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /> /> /> 在本软件中远程控制手机就是通过此短信广播接收机制实现的。当系统收到短信后16 / 77 . 会向需要接收广播的应用发送短信广播,本应用接收广播后就可根据短信内容做出相应的动作了。其服务程序流程图如图4.11所示。 图 4.11 SMS服务流程图 短信接收后台服务关键代码解析如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //创建SMSReceivedBroadcastReceiver类继承BroadcastReceiver类实现接收短信广播 publicclass SMSReceivedBroadcastReceiver extends BroadcastReceiver { //覆写父类onReceive方法执行动作 publicvoid onReceive // 检测防盗保护是否开启 if //通过msgs[i].getDisplayOriginatingAddress<>方法得到来源短信号码 //对比是否为安全手机号 if<<>.equals<"+86" + safenumber>>{} elseif<<>.equals<"12520" + safenumber>>{} elseif<<>.equals // 1.执行GPS定位 if // 2.执行锁定手机 elseif // 3.执行发报警音 elseif // 4.执行销毁数据 elseif } 4.2.2 换卡短信通知 本应用在开机完成后首先接收系统发出的开机完成广播,这时软件就会在后台开始检测SIM卡的IMSI码信息,如果此信息与原保存的IMSI码不一致,则说明手机处于非安全状态。待手机检测到信号,可执行移动服务的时候,服务状态广播就会向手机所有应用发送此广播。当本应用接收到此广播后就会立即向安全手机号发送SIM卡被更换的报告。其服务效果如图4.12所示。 图 4.12 开机检测SIM卡信息流程图 开机检测SIM卡程序主要代码分析如下: 1 2 3 4 5 6 7 8 //创建一个用于开机接收广播的类BootCompleteReceiver publicclass BootCompleteReceiver extends BroadcastReceiver { //覆写父类中的onReceive执行动作 publicvoid onReceive //判断是否开启防盗保护和换卡通知 if //通过getSubscriberId<>方法提取SIM卡IMSI号 String IMSI = scriberId<>; 17 / 77 . 9 10 11 12 13 14 15 16 17 18 19 20 //判断是否与安全IMSI号相等 if<<>.equals return; } //不等则后台向安全手机号发送短信 else { SmsManager manager = ault<>; List safeIMSI + " 的手机,SIM已被更换,更换的IMSI码为:" + IMSI>; for xtMessage 4.2.3 定位手机 Android系统可通过手机的GPS模块为我们提供当前手机的位置信息既经纬度。然后我们再通过向服务器发送地址请求的方式得到手机的具体位置既街道等。其具体实现流程图如图4.13所示。 图 4.13 GPS定位流程图 GPS定位的主要代码分析如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 //建立一个GPS类继承Service public class GPS extends Service{ //创建一个getGPS方法用于获取GPS地址 public void getGPS //得到LocationManager对象 LocationManager locationManager = //获取指定时间指定偏移距离地址信息 tLocationUpdates<_PROVIDER, 0, 0, new TestLocationListener<>>; } //实现LocationListener接口 public class TestLocationListener implements LocationListener{ //当用户位置发生改变时获取经纬度 public void onLocationChanged //指定请求服务器域名 String url = "://apis/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=false"; //创建一个Client对象 Client Client = new DefaultClient<>; //向指定的URL发送请求 18 / 77 . 23 24 25 26 27 28 Response response = e //取得服务器返回的响应 Entity entity = ity<>; //生成Gson对象 Gson gson = new Gson<>; //解析Gson数据并存入testResult testResult = on 有了提供具体位置的GPS服务类,我们只需将信息通过SMS发送到指定安全号码即可远程获得手机的具体位置了。 4.2.4 数据销毁 为了避免隐私泄露,我们需要创建一个专门的类用于处理我们的用户信息,此类应具有备份和删除两个功能。对于用户的隐私文件我们把焦点主要放在联系人和媒体上。因此,我们需要连接并提取联系人和媒体的资料,并拥有删除这些文件的权限方可达到目的。其实现流程图为图4.14所示。 图 4.14 销毁数据流程图 其主要代码分析如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //创建创建TaskService类继承IntentService类 public class TaskService extends IntentService { //覆写父类onHandleIntent方法 protected void onHandleIntent //通过Extra方法提取选择功能 int code = Extra<_TASKCODE, -1>; switch case DE_BACKCONTACTS: Log.i<"guard", "备份联系人">; backContacts<>; break; case DE_DELETECONTACTS: Log.i<"guard", "删除联系人">; deleteContacts<>; break; case DE_DELETEMEDIAS: Log.i<"guard", "删除媒体信息">; deleteMedia_Images<>; break; } 19 / 77 . 4.2.5 锁定手机 当收到锁定手机的指令后,要求手机立刻进入锁屏状态,只能在屏幕上输入安全密码,密码验证通过后手机会恢复正常,要是密码错误则会禁止用户任何操作,直到密码输入正确为止才能使用。其实现效果如图4.15所示。 图 4.15 锁屏流程图 根据程序流程,所以用户一定要在安装完本应用后实现一次锁屏获得ROOT权限后方可远程控制锁屏功能实现。以下为功能实现分析: DevicePolicyManager:顾名思义,这个类的作用是管理设备。通过这个类,我们可以实现屏幕锁定、亮度调节甚至是恢复出厂设置等功能。 DeviceAdminReceiver:这个类的父类是BroadcastReceiver,通过其OnReceive方法可以根据不同的Action执行不同的动作。 这个程序的开发过程大致如下: 要想使用DevicePolicyManager中的方法,首先要定义一个Component。然后通过管理这个组件来启动一个DeviceAdminReceiver。 注册一个广播,用于监听权限的变化,代码在文件中: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 2 3 4 5 6 android:name=".LockScreenAdmin" android:label="string/app_name" android:description="string/app_name" //表示此功能所需的权限 android:permission="_DEVICE_ADMIN"> //表示这个动作的跳转界面 android:resource="xml/lock_screen_admin" /> 其中,android:resource="xml/lock_screen_admin"所指向的内容如下: xmlns:android=""> 实现一个继承自DeviceAdminReceiver的类,实现必须的方法。这个类基本不用写代码,在此略过不表。 这段代码用来在第一次运行的时候激活component,只要激活一次之后,这个component就会一直是激活的。使用startActivityForResult<>可以在onResult方法中调用lockNow<>来锁屏,当不是第一次运行的时候,直接调用lockNow<>锁屏。 20 / 77 . 1 2 3 4 5 6 7 8 9 10 11 12 if w<>; finish<>; } else {// 第一次运行程序 Intent intent = new Intent< _ADD_DEVICE_ADMIN>; ra<_DEVICE_ADMIN, mComponentname>; ra<_ADD_EXPLANATION, "One key lock screen need to active">; startActivityForResult } 4.2.6 发报警音 发报警音的功能实现比较简单,只需要在收到指令后在后台开启影音即可,主要代码如下所示: 1 eamMaxVolume<_MUSIC>;eam2 Volume<_MUSIC>; 4.2.7 数据库存储应用 由于本程序正常工作时运行在后台,所以要运用数据库存放数据。这里数据库的运用在每个单元功能内都必不可少,是否开启防盗功能、是否是第一次启动应用程序、安全手机号、安全密码等数据都交由数据库保存。以安全密码为例在程序中运用代码如下所示: 1 2 3 4 5 6 7 8 9 10 11 //连接数据库生成称对象 SharedPreference sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; //提取安全密码运用 String safenumber = ing<"safenumber", "">; //生成Editor对象 Editor editor = <>; //修改更新数据 ing<"Ssafenumber", Tsafenumber>; //提交数据并保存 editormit<>; 21 / 77 . 5 手机防盗应用测试 上安装本应用软件,另一台用于发送指令。 5.1 防盗应用初始化 如图5.1所示。 图 5.1 初始化设置 在设置界面里开启所有功能。 关闭此防盗应用,退回到手机主界面。 5.2 手机定位功能测试 发送指令:123456#dingwei,〔因为是模拟器,所以需要预先在DDMS里给。5.2所示。 图 5.2 定位功能 由于是模拟器演示,模拟器不支持中文,所以现在返回的是一些乱码,到真机上就能看懂了。 5.3 换卡短信通知功能测试 接下来我们进入DDMS,在Devices窗口里选中emulator-5554,然后在File Explorer窗口中进入data/data/o文件夹,如图5.3所示。 图 5.3 换卡通知date 在shared_prefs文件夹中找到o_文件并将其倒出。如图5.4所示。 图 5.4 数据库位置 这个文件就是数据库文件,将其SIM卡的IMSI号码更改,然后倒入源地址,这样就能模拟换卡的状态了。数据库IMSI码更换前后如图5.5和图5.6所示。 图 5.5 数据库IMSI码更换前 图 5.6 数据库IMSI码更换后 5.4 锁屏功能测试 :123456#suoding 5.7所示。 图 5.7 锁屏功能 22 / 77 . 5.5 销毁数据 由于模拟器没有SD卡,所以本功能只能在真机上测试,其测试方法同样是靠短信指令实现,测试后查看SD卡数据及手机通讯录和媒体数据已全部清空。既销毁数据功能实现。 5.6 发报警音 由于模拟器也无法播放媒体,所以也只能真机测试,由于本功能属于后台运行,真机测试时,当收到指令立即以最大音量报警,既发报警音功能实现。 6 手机防盗应用说明 首先开启防盗应用软件进入初始化界面,在第一个文本框输入安全密码,第二个文本框输入确认密码,两次密码输入必须符合提示要求,否则将不被软件认可。在下面的文本框输入安全手机号码,此号码建议输入亲友,在输入非法号码时,软件将给出相应提示并允许用户重新输入。 手机SIM卡被更换:您向被盗手机发送了锁定手机指令以上两种情况,手机防盗将为您锁定被盗手机,防止别人使用您的手机或查看隐私信息。 手机定位:手机被盗后,可以用任意手机发送定位手机指令到被盗手机,获取手机当前位置,帮您找回手机。定位手机成功后,将会发送短信告知您手机的位置。 *定位手机指令:dingwei#防盗密码 销毁数据:手机被盗后,用安全手机号发送销毁指令到被盗手机,可彻底销毁手机数据,保护隐私不被泄露。销毁的数据包括:通讯录、短信、照片及SD卡的其他数据。特别提醒:销毁数据指令必须使用安全手机号发送。 *销毁数据指令:xiaohui#防盗密码 锁定手机:当手机收到锁定手机指令后会立即锁屏,只有输入正确的安全防盗密码才可解锁手机 。 *锁定手机指令:suoding#防盗密码 发报警音:发觉手机被盗后,可用任意手机发送报警指令到被盗手机。这时被盗手机将发出最大音量的报警声〔即使是静音模式,帮助您快速找到手机。 *发报警音指令:baojing#防盗密码 用户可在设置界面对初始化设置的安全密码和安全手机号进行修改,并可设置防盗功能开关、换卡通知开关以及换卡锁定开关。 结论 在这个高度信息化的时代,手机的丢失总会给人带来很多烦恼,但最让人烦心的是手机中存储的多年好友通讯录、记载着岁月的照片、视频等私人数据都一并丢失。本文所设计的软件就是专门为解决此问题而设计的。 23 / 77 . 本文结合用户手机丢失导致私人信息不安全的问题,总结手机丢失给用户带来的后果,然后根据需求设计软件。本软件基于Android系统平台进行设计,所以文章从软件的UI入手,对比并采用市场上最受用户喜欢的列表式界面设计,应用继承ListActivity的类完美实现。在设置功能按钮的设置界面采用Android系统级UI专用设置类PreferenceActivity参与设计,并以最方便的排版方式实现设置层UI。做好显示后应用Intent传递各UI间的数据,并在关闭软件后将必要的数据存储在SharedPreferences数据库中。在完成整个UI设计后文章逐个介绍每个功能的实现方法及过程。其中运用GPS技术定位手机,并可通过Android系统广播机制,控制手机向指定手机发送当前手机具体位置。要想通过短信控制被盗手机,就要知道被盗手机的手机号码,为此,文章从手机号码来源入手分析,总结得出要想知道当前手机号,必须要获得此手机SIM卡的IMSI码来确定唯一的SIM卡,拥有IMSI码号后便可到移动公司查到当前SIM卡的手机号进而才可实现功能。由问题又引出亲的问题,接下来就要解决如何获取SIM卡IMSI号的问题,这里本章介绍了如何运用Android广播机制中的开机广播和信号广播以及短信广播来监听手机SIM卡状态。在软件检测到SIM卡被更换时,会立即将当前SIM卡信息传递到SMS机制并向指定手机发送指令要求信息。接下来本章具体讲述了在能远程向被盗手机发送指令的情况下如何实现锁屏、销毁隐私数据以及报警等其他防盗功能。 所有功能的实现都在后台完成,这样才能在让非法分子在毫无察觉的情况下绳之以法。本文具体介绍了后台服务的Service,所用到的具体数据都来源于Service服务。GPS的定位、用户隐私数据的备份发送与销毁等功能的实现都是因为拥有强大的后台Service支持才得以实现。 经过大量实验调试,最终本软件实现了所有防盗功能。当安有此防盗软件手机丢失时,后台工作的软件会自动检测到不安全状态,待安全手机号收到目标手机当前手机号后便可通过防盗指令控制被盗手机锁屏并以最大音量发报警音,在不法分子还没来得反应的时候,公安人员已经按照软件所提供的GPS定位地址将其制服并拿回属于用户的手机。如果不法分子为了消赃毁坏了手机,那我想在手机被盗的第一时刻用户就已经把自己的重要信息备份出来了,再无忧患所言。 致谢 经过几个月的努力,本人的毕业设计"基于Android系统的手机防盗应用"以完美完成。作为一个本科生的毕业设计,由于经验的匮乏,难免有许多考虑不周全的地方,如果没有导师的督促指导,以及一起工作的同学们的支持,想要完成这个设计是难以想象的。 首先要感谢的是我的导师刘军华老师,在我当初想要以Android系统应用作为我毕设题目的时候,给了我很大的鼓励与支持。本来在学校做毕设的同学,毕设题目是学校的老师指定好的,学生需在所有题目中选择一个作为自己的毕设来做。我学的专业是电子信息工程,所学的知识以硬件为主,因此所有的题目都是以硬件为主的,特别是我导师刘军华的题目,基本都是以ARM研究为主的。但是我对Android系统这个纯软件方向比较感兴趣,就想做个Android的应用作为自己的毕设,所以很是为难。但当我和刘老师说了我的想法后,他没有反对,反而非常支持,并想给我介绍到一家做Android的公司去学习并完成毕设。而后又帮我设定并确定毕设要完成的任务,如我愿的以"基于Android系统的手机防盗应用"项目做为了自己的毕业设计。也只有老师这样的抉择才能实现我现在的毕业设计。在这里对刘老师深表感谢! 对于Android系统我属于白手起家,甚至连Java语言都不是很扎实,所以一上来就像做应用是根本不可能的事。我的同学对Android有一些了解,知道我要做Android系统24 / 77 . 应用的毕设后主动帮我找资料,介绍Android的个大论坛,以及其编译环境等,给初学者的我指明了学习的方向,少走了很多弯路,非常感谢你们! 关于我对Android系统学习影响最大的就是mars老师了,mars老师是Android教学视频的老师,虽然他不认识我,但我几乎说有的Android系统知识都来源于mars老师的课程。mars老师不仅Android系统讲得好,而且还为我这样的初学者专门做了一系列Java4Android的视频很好的弥补了我的Java基础不足的缺陷。这里郑重感谢网络教师mars老师,感谢您的教导,祝您的教育事业越办越好! 还不能忘了感谢我们最常用的百度和Google公司,他们的文库为我提供了巨大地资料,决绝了我很多问题。还有Android联盟里的同志们,有了你们的帮助才使我少走弯路,在我不理解的时候你们耐心讲解,虽然我们并不知道彼此的容颜,但我却深知你们那份乐于助人的心。真心的感谢您们,祝你们工作顺利! 感谢我的父母,在我在家做毕设的时候,他们耐心的为我做饭,尽最大努力帮我排除一切影响因素,儿子在这里谢谢您们!祝您们身体健康! 一路走来,要感谢的人太多了,是你们的帮助才有我现在的成就,谢谢你们! 参考文献 1 张浩,基于Android平台手机防盗追踪功能的实现[J].XX理工大学信息工程与自动化学院,20XX8月17日. 2 盖锁林,王世江.Google Android开发入门指南[M].第二版.人民邮电出版社,20XX2月. 3 吴亚峰,苏亚光. Google Android应用案例开发大全[M].人民邮电出版社,20XX9月1日 4 胡辛征,高洪霞.21天学通Java[M].第二版.电子工业出版社,20XX7月. 5 E2EColud工作室.深入浅出Google Android[M].人民邮电出版社,2009. 6 林城.Android2.3应用开发实战[M].机械工业出版社,20XX6月1日. 7 李刚.疯狂Android讲义[M].电子工业出版社,20XX6月22日. 8 吴亚峰,索依娜,百纳科技.Android核心技术与实例详解[M].电子工业出版社,20XX10月1日. 9 余志龙,王世江.Google Android SDK开发范例大全[M].人民邮电出版社,20XX6月1日. 10 靳岩,姚尚朗.Android开发入门与实战[M].人民邮电出版社,20XX7月1日. 11 的个人论坛[EB/OL]., 20XX9月10日/20XX3月5日. 12 d视频教程[CD].mars视频,20XX11月/20XX3月. 13 4Android视频教程[CD].mars视频,20XX11月/20XX3月. 14 d之PreferenceActivity[J/OL].CSDN,20XX1月16日/20XX4月9日. 15 ew and CheckBox[J/OL].ITCYC,20XX9月30日/20XX4月20日. 16 ew加在性能优化ViewHolder[J/OL].CSDN,20XX12月20日/20XX5月3日. 17 d ListView详解[J/OL].android diordna,20XX12月19日/20XX5月15日. 18 Sayed Android 3[M].Apress,2011. 19 Donn d Application Development for Dummies[M].HUNGRY 25 / 77 . MINDS,2010.11.22. 20 Mark ing Android 3[M].Apress,2011. 21 Ed Burnett,Susannah Davidson , Android: Introducing Google's Mobile Development Platform[M].Pragmatic Bookshelf,2011. 附录一 图片: 附录二 一 相关下载 <1> java JDK下载: 进入该网页: 如下图: 选择 Download JDK 只下载JDK,无需下载jre. <2>eclipse下载 进入该网页: 如下图: 我们选择第一个<即eclipse IDE for java EE Developers> <3>下载Android SDK 说明: Android SDK两种下载版本,一种是包含具体版本的SDK的,一种是只有升级工具,而不包含具体的SDK版本,后一种大概20多M,前一种70多M。 <1>安装jdk 6u19:安装完成即可,无需配置环境变量 26 / 77 . <2>解压eclipse:eclipse无需安装,解压后,直接打开就行 <3>解压android sdk:这个也无需安装,解压后供后面使用 <4>最终有三个文件夹,如下图: 三 Eclipse配置 1 安装android 开发插件 <1>打开Eclipse, 在菜单栏上选择 help->Install New SoftWare 出现如下界面: 点击 Add按钮,出现如下界面 输入网址: 名称: Android <这里可以自定义> 点击OK,将出现如下界面 点击 Next按钮 ,出现如下界面: 点击Next按钮,出现如下界面: 选择 I accept the terms of the license agreements 点击Next,进入安装插件界面 安装完成后,出现如下界面 点击Yes按钮,重启Eclipse 2 配置android sdk <1>点击菜单window->preferences,进入如下界面 选择你的android SDK解压后的目录,选错了就会报错,这个是升级工具,目前还没有一个版本的SDK 〔2升级SDK版本,选择菜单 window->Android sdk and avd manager 出现如下界面 选择update all按钮,出现如下界面 选择左边的某一项,点击accept表示安装,点击reject表示不安装,我这里只选了SDK 2.1 和samples for api 7 , 自己可以任意自定义,确定后,选择install按钮,进入安装界面如下: 安装完成如下: <3>新建AVD 点击New按钮后,进入如下界面: 名称可以随便取,target选择你需要的SDK版本,SD卡大小自定义,点击 Create AVD,得到如下结果 如上显示创建AVD完毕 附录三 源代码: 27 / 77 . src文件java代码: 1. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package o; import ty; import ; public class Baojing extends Activity{ Override protected void onCreate // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity setContentView } } package o; import ; import astReceiver; import t; import ; import Preferences; import ager; import onyManager; public class BootCompleteReceiver extends BroadcastReceiver { SharedPreferences sp; TelephonyManager tm; Override public void onReceive sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; tm = temService boolean isprotect = lean<"protect", false>; 28 / 77 2. . 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 1 2 3 4 5 6 7 8 9 10 11 12 13 boolean issendID = lean<"sendID", false>; n<"开机">; n<"isprotect------->" + isprotect>; n<"issendID------->" + issendID>; if String safeIMSI = ing<"IMSI", "">; String safenumber = ing<"safenumber", "">; //IMSI String IMSI = scriberId<>; n<"subscriberId-------->"+IMSI>; if<<>.equals return; } else { //SmsManager SmsManager manager = ault<>; List + " 的手机,SIM已被更换,更换的IMSI码为:" + IMSI>; for xtMessage n<"已发送">; } } } else { return; } } } package o; import ty; import ; public class Chakan extends Activity{ Override protected void onCreate // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity 29 / 77 3. . 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 } } setContentView<>; 4. package o; import ty; import ; public class Dingwei extends Activity{ Override protected void onCreate // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity setContentView; } } package o; import ty; import ; import Preferences; import ; import ; import onyManager; import ; import kListener; import ; import xt; import ; public class First extends Activity{ boolean isFirst; SharedPreferences sp; TelephonyManager tm; /** Called when the activity is first created. */ 30 / 77 5. . 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 Override public void onCreate te setContentView<>; // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity sp = redPreferences<"o_preferences", MODE_WORLD_READABLE>; //IMSI tm = final String IMSI = scriberId<>; final EditText et_password1 = final EditText et_password2 = final EditText et_safenumber = Button bt_sure = Button bt_exit = bt_lickListener public void onClick String Str_password1 = et_t<>.toString<>; String Str_password2 = et_t<>.toString<>; String Str_safenumber = et_t<>.toString<>; if xt<, "密码不能为空", _LONG>.show<>; return; } else if 12>{ xt<, "请输入6-12位数字或字母的密码", _LONG>.show<>; return; } else if.equals xt<, "密码两次输入不一致,请重新输入", _LONG>.show<>; 31 / 77 . 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 return; } else if xt<, "手机号码不能为空_LONG>.show<>; return; } else if xt<, "手机号码错误_LONG>.show<>; return; } else{ // 建立数据库编辑对象 Editor editor = <>; // 储存当前手机IMSI到数据库 ing<"IMSI", IMSI>; // 储存密码到数据库 ing<"password", Str_password1>; // 储存安全手机号到数据库 ing<"safenumber", Str_safenumber>; // 改first值为false,再次打开应用时不进入此Activity lean<"first", false>; // 提交改动到数据库并保存 editormit<>; // 创建intent对象 Intent intent = new Intent<>; // 指明跳转Activity ss<, >; ctivity } } }>; bt_lickListener public void onClick // 调用exit方法完全退出 tance<>.exit<>; } }>; } } ", ", 6. 32 / 77 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package o; import edReader; import treamReader; import ; import sult; import ..Entity; import ..Response; import ..; import ..; import ..tClient; import e; import t; import ; import Preferences; import on; import onListener; import onManager; import ; import r; import ager; import ; public class GPS extends Service{ TestResult testResult; String Gsafenumber; SharedPreferences sp; int a = 0; public void getGPS a = 1; sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; Gsafenumber = ing<"Ssafenumber", "">; n<"----------->1">; LocationManager locationManager = n<"----------->2">; tLocationUpdates<_PROVIDER, 0, 0, new TestLocationListener<>>; 33 / 77 . 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 n<"----------->3">; } public class TestLocationListener implements LocationListener{ Override public void onLocationChanged n<"<<<1">; // TODO Auto-generated method stub n n if{ a = 0; String url = "://apis/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=false"; n<"<<<2">; //创建一个Client对象 Client Client = new DefaultClient<>; n<"<<<3">; String responseData = ""; n<"<<<4">; try{ //向指定的URL发送请求 Response response = e n<"<<<5">; //取得服务器返回的响应 Entity entity = ity<>; n<"<<<6">; BufferedReader bufferedReader = new BufferedReader InputStreamReader n<"<<<7">; String line = ""; n<"<<<8">; while< responseData = responseData + line; } n<"<<<9">; } catch tackTrace<>; } n<"<<<10">; 34 / 77 . 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 Gson gson = new Gson<>; n<"<<<11">; testResult = on n<"<<<12">; n SmsManager manager = ault<>; if List n<"已发送">; for xtMessage n<"<<<13">; } } else{ List testResult >; n<"已发送">; for xtMessage n<"<<<13">; } } } } Override public void onProviderDisabled // TODO Auto-generated method stub } Override public void onProviderEnabled // TODO Auto-generated method stub } Override public void onStatusChanged Bundle extras> { 35 / 77 . 130 131 132 133 134 135 136 137 138 139 140 141 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 } } } // TODO Auto-generated method stub Override public IBinder onBind // TODO Auto-generated method stub return null; } 7. package o; import ty; import ; public class Huanka extends Activity{ Override protected void onCreate // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity setContentView<>; } } package o; import ist; import p; import ialog; import tivity; import ; import Preferences; import ; import ; import Inflater; 36 / 77 8. . 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 import ; import kListener; import ; import xt; import ew; import Adapter; import ; public class Main extends ListActivity { boolean isFirst; boolean isDialog; SharedPreferences sp; AlertDialog showputPWDialog; private static final int tiyan = 0; //防盗功能体验 private static final int chakan = 1; //防盗指令查看 private static final int shezhi = 2; //防盗信息设置 /** Called when the activity is first created. */ public void getMaxVolume<>{ } Override public void onCreate te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity sp = redPreferences<"o_preferences", MODE_WORLD_READABLE>; isFirst = lean<"first", true>; isDialog = lean<"Dialog", false>; if Intent intent = new Intent<>; ss<, >; ctivity } else{ /////////////////测试区///////////// // Editor editor = <>; // lean<"first", true>; // editormit<>; //////////////////////////////////// 37 / 77 . 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 if putPWDialog<>; } else{ init<>; Editor editor = <>; lean<"Dialog", true>; editormit<>; } setContentView<>; } } private void init<> { /* Button bt_exit1 = bt_lickListener public void onClick // 调用exit方法完全退出 tance<>.exit<>; } }>;*/ ArrayList HashMap HashMap HashMap <"fangdao", "防盗功能体验">; <"jianjie", "了解手机防盗提供哪些功能">; <"img", >; <"jiantou", u>; <"fangdao", "防盗指令查看">; <"jianjie", "手机丢失后如何遥控操作">; <"img", >; <"jiantou", u>; <"fangdao", "防盗信息设置">; <"jianjie", "修改防盗密码、安全手机号等">; <"img", >; <"jiantou", u>; 38 / 77 . 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 SimpleAdapter listAdapter = new SimpleAdapter new String[]{"fangdao","jianjie","img","jiantou"}, new int[]{,,,}>; setListAdapter } private void putPWDialog<> { LayoutInflater inflater = View view = e final EditText et_password = Button btn_sure = Button btn_exit = r builder = new r le<"输入密码">; w showputPWDialog = <>; <>; btn_lickListener public void onClick String password = et_t<>.toString<>; String savedPassword = ing<"password", "">; if<<>.equals<"">> { xt<, "密码不能为空", _LONG>.show<>; return; } else if<<>.equals s<>; init<>; } else { xt<, "密码错误", _LONG>.show<>; 39 / 77 . 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 return; } } }>; btn_lickListener public void onClick tance<>.exit<>; } }>; } //选择菜单选项并进入选项页面 Override protected void onListItemClick { // TODO Auto-generated method stub ItemClick Intent intent = new Intent<>; n<"1">; if { ss<,>; ctivity } else if { ss<,>; ctivity } else if { ss<,>; ctivity } } } package o; import List; 40 / 77 9. 1 2 3 . 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 1 2 3 4 5 6 7 8 9 import ; import ty; import ation; public class MyApplication extends Application { private List private static MyApplication instance; private MyApplication<>{} //单例模式中获取唯一的MyApplication实例 public static MyApplication getInstance<>{ if instance = new MyApplication<>; } return instance; } //添加Activity到容器中 public void addActivity } //遍历所有Activity并finish public void exit<>{ for <>; } <0>; } } package o; import ty; import ; public class Paizhao extends Activity{ Override protected void onCreate 41 / 77 10. . 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity setContentView } } package o; publicclass RunnableImpl implements Runnable { Override publicvoid run<> { // TODO Auto-generated method stub try{ } } } } n <5000>; 11. catch 12. package o; import ; import enceActivity; public class Shezhi extends PreferenceActivity{ Override publicvoid onCreate te } } addPreferencesFromResource<>; 13. package o; import ; 42 / 77 . 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import astReceiver; import t; import ; import Preferences; import ; import ager; import onyManager; public class Signal extends BroadcastReceiver{ SharedPreferences sp; TelephonyManager tm; Override public void onReceive sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; tm = temService boolean isprotect = lean<"protect", false>; //防盗开关 boolean issendID = lean<"sendID", false>; //发送IMSI boolean isBoot = lean<"Boot", false>; //开机启动 n<"信号">; n<"isprotect------->" + isprotect>; n<"issendID------->" + issendID>; n<"isBoot------->" + isBoot>; if Editor editor = <>; // 储存当前手机开关状态到数据库 lean<"Boot", false>; // 提交改动到数据库并保存 editormit<>; String safeIMSI = ing<"IMSI", "">; String safenumber = ing<"safenumber", "">; //IMSI String IMSI = scriberId<>; n<"subscriberId-------->"+IMSI>; if<<>.equals return; } else { //SmsManager SmsManager manager = ault<>; 43 / 77 . 48 49 50 51 52 53 54 55 56 57 58 59 60 61 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 List + " 的手机,SIM已被更换,更换的IMSI码为:" + IMSI>; for xtMessage n<"已发送">; } } } else { return; } } } package o; import astReceiver; import t; import ; import Preferences; import ; import anager; import sage; import onyManager; public class SMSReceivedBroadcastReceiver extends BroadcastReceiver { protected AudioManager mAudioManager; SharedPreferences sp; TelephonyManager tm; String Tsafenumber; int Inta; Override public void onReceive sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; tm = temService boolean isprotect = lean<"protect", false>; String safenumber = ing<"safenumber", "">; 44 / 77 14. . 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 // // // // // // // String password = ing<"paddword", "">; String IMSI = scriberId<>; n<"111">; Intent intent2 = new Intent<>; ss ervice n 检测防盗保护是否开启 if n<"开关开启">; Inta = 0; 接收短信并装入msgs Object[] object = byte[][] pdus = new byte[][]; for pdus[i] = } SmsMessage[] msgs = new SmsMessage[]; for msgs[i] = FromPdu } for oriAddress为短信来源号码 String oriAddress = msgs[i].getDisplayOriginatingAddress<>; n<"safenumber:"+safenumber>; n<"oriAddress:"+oriAddress>; n<"<>:"+<>>; n<<>.equals if<<>.equals<"+86" + safenumber>>{ n<"+86号码吻合">; Tsafenumber = "+86" + safenumber; Inta = 1; } else if<<>.equals<"12520" + safenumber>>{ n<"12520号码吻合">; Tsafenumber = "12520" + safenumber; Inta = 1; } else if<<>.equals n<"原号码吻合">; 45 / 77 . 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 // // // // } Tsafenumber = safenumber; Inta = 1; n if Editor editor = <>; ing<"Ssafenumber", Tsafenumber>; editormit<>; String body = msgs[i].getDisplayMessageBody<>; 定位 if n<"GPS定位">; abortBroadcast<>; GPS gps = new GPS<>; n<"---->gps">; } 2.锁定手机 else if abortBroadcast<>; } 3.发报警音 else if n<"报警">; abortBroadcast<>; n<"获取最大音量">; eamMaxVolume<_MUSIC>; eamVolume<_MUSIC>; n<"报警完成">; } 4.销毁数据 else if abortBroadcast<>; } } 46 / 77 2023年12月16日发(作者:戚冉冉) . 摘要 近年来,智能手机的功能日趋强大,移动终端应用程序层出不穷。由于现在人们的工作繁忙,手机的丢失似乎也成为常有的事。与之带来最让人烦心的是私人数据的丢失及带来的不安全隐患。基于以上原因,本文设计了一款手机防盗追踪软件。本软件利用 Android系统的广播机制,当手机用户开启防盗追踪功能后,本程序将后台监听手机开机启动、信号状态、短信收发以及位置的改变,通过监听手机用户 SIM 卡的 IMSI码的改变来判断手机安全状态,监听并截获安全短信内容,实现非法用户的手机号码向合法用户预先设置的安全号码发送特殊信息的功能,告知用户当前手机状态和位置信息,并可通过安全短信控制被盗手机锁屏、销毁隐私数据、发报警音等功能。最后将设计完成的软件进行测试,其所有功能都完美实现,真正起到了手机防盗追踪的作用。 关键词:Android系统 手机防盗 广播机制 监听器1 / 77 . ABSTRACT In recent years, the intelligent mobile phone function is powerful, the mobile terminal application emerge in an endless stream. Because now people's busy work, the lost mobile phone also seems to be a common thing. And bring the most disturbing is a private data loss and insecurity hidden trouble. Based on the above reasons, this paper introduces the design of a mobile phone anti-theft tracking software. This software uses Android system broadcast mechanism, when the mobile phone users to open anti-theft tracking function, the program will monitor the background mobile phone boot, signal condition, send and receive text messages and a change of location, through the monitoring mobile phone user SIM card IMSI code changes to determine mobile phone safety state, monitor and intercepts a secure message content, realize the illegal user the mobile phone number to the legitimate user preset safety numbers to send special message to inform the user of mobile phone function, current status and location information, and through SMS security control of stolen mobile phone lock screen, the destruction of privacy data, send alarm sound and other functions. Finally completed the design of the software testing, all of its functions are perfect, played a real mobile phone anti-theft tracking function. Keywords: Android system DroidRing Broadcasting mechanism Listener 目录 1绪论1 1.1应用开发研究背景与意义1 1.2国内外研究现状1 国内研究状况1 国外研究状况2 1.3开发研究内容2 2手机防盗应用开发的基础2 2.1Java基础2 2.2Android基础3 3手机防盗应用方案的设计3 3.1UI设计4 3.1.1 UI窗口层5 3.1.2 UI主层5 3.1.3 UI功能体验层5 3.1.4 UI指令查看层6 3.1.5 UI信息设置层6 3.2Function设计6 应用初始化6 1 / 77 . 功能选择7 功能体验7 功能查看7 功能设置7 3.3Service设计8 数据库存储服务8 监听按钮事件服务8 开机启动和短信广播服务8 GPS服务9 私人数据的管理9 4手机防盗应用方案的实施9 4.1UI的实现9 Activity9 ListActivity12 PreferenceActivity14 Dialog15 4.2由Sever支持的Function实现16 广播机制服务16 换卡短信通知17 定位手机18 数据销毁19 锁定手机20 发报警音21 数据库存储应用21 5手机防盗应用测试22 5.1防盗应用初始化22 5.2手机定位功能测试22 5.3换卡短信通知功能测试22 5.4锁屏功能测试22 5.5销毁数据23 5.6发报警音23 6手机防盗应用说明23 结论23 致谢24 参考文献25 附录一26 附录二26 附录三27 2 / 77 . 1 绪论 1.1 应用开发研究背景与意义 随着 3G 技术的不断发展,手机移动应用开发成为目前热门的技术之一。种类繁多的手机应用以及先进的硬件,使得手机已经不完全是用来通话的工具了,它巧妙的融合了PDA 关于手机我们能想到很多人们担心的话题。而最为愁人的就是现在的手机大都兼容各种卡,一旦丢失,就会机卡两空。在我们忙碌的工作生活中,似乎手机丢失已经成为了一种自然的事情。其实不论你的手机值不值钱,丢东西的事情本身就会让人头疼。那么该怎样制服盗机者,在我们提高自身防范意识的同时,适当的为手机增加些防盗功能也是应该的。 在众多手机操作系统中,Android手机操作系统由于他的完全开放性使得其应用人群独占鳌头。 图1.1 Android系统构架 Android〔智能机器人是 Google 开发的基于 Linux 平台的开源手机操作系统,该平台由操作系统、中间件、用户界面和应用软件组成,其系统构架如图1.1所示,被誉为第一个完整、开发而免费的移动平台。Google 提供在线文档、工具、论坛和软件开发工具包等资源,以便开发者在 Android 平台上开发应用程序。并且众多手机制造商,如三星、摩托罗拉、HTC、LG和小米等,还有许多半导体公司,如英特尔、XX仪器、NVIDIA 和高通等,参与 Android 手机设计。由此可见,Android发展前景不容小觑,已成为目前主流的手机操作系统之一。Android 手机设备运行在 Linux 操作系统下,这使得其上运行的 Android 应用程序具有很强的安全性。每一个 Android 应用程序均运行在不同的进程中,每个进程都对应一个 Dalvik 虚拟机的实例。基于 Java 虚拟机,Dalvik 为移动设备进行了优化设计。Dalvik 虚拟机具有较小的内存占用,而且多个 Dalvik 虚拟机的实例在手机设备中可以并发运行。Android 应用程序为托管代码,所以,由应用程序而导致系统崩溃的可能性很小,这也降低了设备崩溃的可能性[2]。 综观Android手机系统,我们不难发现,应用本系统开发手机的生产厂商多,用户基数大,安全性高,并受到众多大牌公司支持,基于以上优越性,在Android系统上开发本手机防盗应用具有重要的现实意义。 1.2 国内外研究现状 1.2.1 国内研究状况 毋庸置疑手机防盗应用肯定归属于手机安全类软件,对于安全软件的开发与研究又是杀毒软件公司首要考虑的功能之一,所以国内的很多杀毒软件公司在自己的产品中都涉及了防盗功能。例如金山手机卫士、360手机卫士、QQ手机管家等保护手机系统安全类软件中具有防盗功能。 1 / 77 . 图 1.1手机防盗 1.2.2 国外研究状况 英国一家手机服务公司宣布推出一整套手机防盗软件的服务,使用该服务的用户在手机被盗后不仅可及时转移手机信息,手机还能发出刺耳鸣声,让窃贼根本无法使用所盗手机。当用户在手机中安装这款软件后,每月只需支付10英镑〔约合18美元即可享受防盗服务。一旦手机被盗,用户可立即致电公司。公司随即向被盗手机发送指令,将里面存储的信息全部转移至安全服务器,随后锁定手机功能并使手机发出刺耳的鸣声。 该公司介绍说,防盗程序启动后,窃贼即便更换SIM卡也无法解除锁定。此外,只要不取出电池,鸣声就不会停止。用户购买新手机后,还可申请将原来手机中的全部信息转移至新手机内。据伦敦市警察局统计,该市每月约有1万部手机被盗。警方希望这一手机防盗软件能改善这一局面[3]。 美国的苹果公司,在其官网上向所有用户提供了一项云端技术服务,只要苹果手机或者苹果的其他移动设备,都可以享受到手机卫星定位功能。具体做法是:首先,在拿到苹果后,你要先申请属于你的Apple ID,登录苹果商店或者在Mobile Me上注册,这个应用就可以实时定位你的iPhone的位置。 图 1.2 苹果手机防盗 1.3 开发研究内容 从上面的应用我们可以看出,无论是国内还是国外,只要是致力于防盗功能的软件,其最核心功能都用到了GPS、锁屏、媒体播放等。因此,综合以上各软件优点,新型的手机防盗应用软件应具有GPS定位、被盗时锁屏、通过短信控制以最大音量发报警音、远程销毁隐私数据以及偷拍盗窃者长相等功能。同时,防盗应用软件也应充分利用操作系统固有的资源。 因此,本课题的任务是设计一款基于 Android 平台开发的一款手机防盗软件。通过Android系统中的广播机制后台监听手机的各种状态,根据状态的改变来判断手机是否安全。一旦手机丢失,我们便可通过向失窃手机发送指令短信的方式,应用Android系统的GPS 2 手机防盗应用开发的基础 2.1 Java基础 Java由Sun . [4]。Java语言具有极强的跨平台能力,多语言的支持,占据着互联网开发语言的首位。 基于Android系统的手机应用全部应用Java语言编写完成。所以,想在Android系统上做出一个好的应用来不仅要会Java语言,而且还要运用熟练。对此,我通过观看Mars老师的Java4Android视频和对Java相关书籍的精读与练习,强化了自己对Java语言的掌握,使我对Java的运用能力有了很大的提高,并为编写与设计Android应用奠定了良好地基础。 2.2 Android基础 知己知彼者百战百胜。想在Android系统上做开发,就一定要了解Android系统,知道他的由来和内部构造。 Android操作系统最初主要支持手机,20XXGoogle收购了刚刚成立22个月的Android公司,也正是有了在Google这样巨头公司下发展的机会才使得Android系统迅猛发展。20XX11月5日,以Google为首的34家公司宣布成立OHA 最早的Android版本为Android 1.0〔发条机器人,自Android系统发布第一版本到现在已经更新多次。Android1.1Beta〔阿童木 20XX9月发布的Android第一版,后来由于涉及到版权问题,Goolge将其命名规则变更为用甜点作为它们系统版本的代号的命名方法。其各版本logo如图2.1所示。 Android 1.5 Cupcake〔纸杯蛋糕 Android 1.6Donut〔甜甜圈 AndroidEclair〔松饼 Froyo〔冻酸奶 Android 2.3Gingerbread〔姜饼 Android 3.0Honeycomb〔蜂巢 Android 3.1Honeycomb〔蜂巢 Android 3.2Honeycomb〔蜂巢 图 2.1 Android版本 Android 4.0 Ice Cream Sandwich〔冰激凌XX治 Android 5.0Jelly Bean〔果冻豆 3 手机防盗应用方案的设计 在电子领域,要想拥有很好的市场前景,就必须应用最先进的设计技术、最成熟的设计理念以及最合理的设计方法才能使得产品得以发展。于是我选择了目前市场应用最为广泛的金山手机卫士、360手机卫士和QQ手机管家其中的手机防盗部分作为参考。学习并对比这3家在此功能上的不同。分别在UI 表格 1 手机防盗UI、Function和Service对比 比对参数 金山手机防盗 360手机防盗 QQ手机防盗 3 / 77 . 3步 3步 4步 6个 6个 5个 UI 以文字为主 视图+文字 以文字为主 灰色 白色 白色 换卡短信通知 换卡短信通知 数据删除 销毁数据 删除数据 手机定位 定位手机 追踪手机位置 找回密码 主要功能 发报警音 响报警音 远程锁机 Function 锁定手机 锁定手机 防盗拍照 输入错误提示 一般 精准 一般 GPS定位功能 有 有 有 Service 短信监听发送 有 有 有 开机监听 有 有 无 从表格1中我们可以很清楚的看到,在UI方面360更为注重,以多图少字的方式展现功能,使用户更加喜欢,也方便了用户对功能的理解。不过从Function上来看,金山手机防盗的设计就要优于另外两家,在所有功能的基础上还加进了一项防盗拍照,这是仅有4项功能的QQ所没能想到的安全设计。 综合以上软件优点便是此软件将要实现并达到的目标。因此我将结合360的UI、金山的Function和Service做出一款即看上去漂亮而且功能也强大的手机防盗软件。 初始化设置步骤 主界面信息栏个数 进入应用层界面效果 UI层底色 3.1 UI设计 UI设计是指对软件的人机交互、操作逻辑、界面美观的整体设计。好的UI设计不仅是让软件变得有个性有品味,还要让软件的操作变得舒适、简单、自由,充分体现软件的定位和特点。如图3.1就是一副很美观的UI。 图 3.1UI 软件设计可分为两个部分:编码设计与UI设计。编码设计大家都很熟悉,但是UI设计还是一个很陌生的词,即使一些专门从事网站与多媒体设计的人也不完全理解UI的意思。UI的本意是用户界面,是英文User和 Interface的缩写。从字面上看是用户与界面2个组成部分,但实际上还包括用户与界面之间的交互关系。 在飞速发展的电子产品中,界面设计工作一点点的被重视起来。做界面设计的"美工"也随之被称之为"UI设计师"或"UI工程师"。其实软件界面设计就像工业产品中的工业造型设计一样,是产品的重要卖点。一个电子产品拥有美观的界面会给人带来舒适的视觉享受,拉近人与商品的距离,为商家创造卖点。界面设计不是单纯的美术绘画,他需要定位使用者、使用环境、使用方式并且为最终用户而设计,是建立在科学性之上的艺术设计[6]。 综合上述UI设计特点,加上方便实用的设计特点,我将本手机防盗应用的UI分为了5层,他们由UI窗口层、UI主层、UI功能体验层、UI功能查看层和UI功能设置层组成。其层次流程如图3.2所示。 图 3.2 UI总流程图 4 / 77 . 3.1.1 UI窗口层 UI窗口层分为两个界面,一个是初次开启应用时进入的设置初始化界面,另一个则是用户在非第一次开启应用时弹出的用户身份验证窗口。 图 3.3 初始化设置 当用户第一次开启应用时,展现在用户眼前的是一个设置初始化界面,如图3.3所示。用户可按照相应提示完成放到设置,其中包括设置防盗安全密码和设置安全号码。防盗安全密码将用于验证应用本软件用户的身份,在非第一次开启此防盗软件时将需要用户输入防盗安全密码。另外,设置好的防盗安全密码将会编进防盗指令,用于控制手机实现相应的操作。安全手机号的设置非常重要,设置成功后,此号码将被认为是唯一可信赖的手机号码,当手机被盗后,防盗软件将会按照指令向安全号码手机发送手机状态。 图 3.4 验证窗口 图3.4展现的是用户在非首次开启应用时弹出的验证用户信息窗口。此通行密码为用户设置的防盗安全密码,通过此方式保证了用户设置信息的安全性。 UI窗口层为本应用软件的最顶层,此层的UI设计好坏决定了用户对本软件的第一印象,所以要想得到用户的肯定,这层的设计一定要做好。为此,在选择文字的字体、颜色、大小以及摆放位置做了无数次的调整,努力达到最好、最舒适。除了这些我还在输入文本框里加进了提示信息如:输入密码框里的"6~12位数字或字母"等,在方便用户应用的同时也美化了UI。 3.1.2 UI主层 UI主层是个选择界面如图3.5,本层为用户提供3种主要操作,分别为防盗功能体验、防盗指令查看、防盗信息设置。 图 3.5 UI主层 在本层UI的上面是一个宇宙图片,寓意着安装本应用后,即使你的手机被带到了宇宙我们也能找到它,当然这有些夸张了,不过我们还是要对此软件充满信任的。 除了这张宇宙图片我还在每个选项前后都加附上了相应功能的logo,学习360的多图设计,用视觉告诉用户本条选项的功能。 为达到UI布局整齐的效果,我采用列表式布局,将选项按照用户需求量进行排布,这样的布局可是UI实现整齐、清晰、功能突出等效果,属于理想的UI设计。 3.1.3 UI功能体验层 UI功能体验层如图3.6所示,此UI界面同样继承优良设计布局方案将本应用所有功能统一以列表形式列出,最前端图标代表着此条选项所要实现的功能,然后每个选项的功能说明以大字功能名加小子简要说明的形式整齐的展现在界面上,让用户对选项功能一目了然。 图 3.6 UI功能体验层 当用户点击进入UI功能体验层的每个选项后,就会看到每个功能实现的具体说明,而且在每个可以单机实验的功能里都加进了功能体验按钮,可以让用户体验本功能的真5 / 77 . 实效果。其效果图见附录一。 3.1.4 UI指令查看层 在UI指令查看层,总结罗列了开启每个防盗功能的防盗指令,用户可以在这里方便快捷的得到所需防盗指令,如图3.7所示。 图 3.7 UI指令查看层 3.1.5 UI信息设置层 UI的设置层是UI非常重要的一个视图层,此层要以最方便,最简约,最快捷为核心排版设计,而且要尽量覆盖本软件的所有功能设置。基于以上要点,首先总结本防盗软件的设置功能如表2。 表格 2设置功能 所需功能 功能目的 功能体现设置此功能键的意义 形式 防盗开关 方便控制防盗功能开关按钮 可以方便用户对防盗应用软件的控制,无的开启与关闭 需卸载就能关闭防盗 换卡锁定避免因用户自己换开关按钮 在避免发送错误指令的同时,用户也可通开关 卡执行错误指令 过此开关对锁定功能进行单独体验 换卡短信避免因用户自己换开关按钮 在避免发送错误指令的同时,用户也可通通知开关 卡执行错误指令 过此开关对换卡短信通知功能进行单独体验 防盗密码用于修改安全密码 加密形式 方便用户在首次初始化后改变防盗安全重置 密码 安全手机用于修改安全手机显示预置方便用户在首次初始化后改变防盗安全号重置 号码 号码 手机 按照表格2中的功能需求,我在设置UI里建立了与之相应的5个控件,以方便用户对软件的应用控制。最终设计出图3.8的效果来实现功能。 图 3.8 UI设置层 3.2 Function设计 我们在UI的设计中了解到一款软件拥有一个美观的UI是多么重要,那我们该如何实现这种华丽的显示呢?这就需要又一个很好的后台设计既功能设计。 3.2.1 应用初始化 初始化界面是让用户设置信息用的,所以首先我要告诉用户需要设置的信息都有哪些,介绍完后还要在相应的位置给出用于填写信息的控件。 6 / 77 . 这里我们用Android中最常用的TextView和EditText两个布局控件满足需求。并且在EditText里加入hint属性显示相关提示信息。对于密码的设置,我们都希望处于不可见状态以保证我们个人信息的安全,我用password属性来控制输入时的显示状态。在整个UI的最下面我还放置了两个按钮,方便用户的进一步应用和退出,此功能将用Button控件实现。 3.2.2 功能选择 功能选择的UI主要分为两部分,可以从上到下分为两段,在布局控件中用LinearLayout实现,并设置排版属性为垂直布局。上半部为一个图片,下面则需要一个List控件完成效果,整个UI的程序将用继承ListActivity类来描述已达到选项罗列的效果[7]。 图3.9为Android的文件管理。在Android中所有资源文件要统一管理并放到res文件夹中,并把每个资源都加上各自的ID,以方便调用。所有的调用ID则会放到gen文件夹下的文件中进行统一遍历,我们所要的资源便可从这里索取。例如我们的宇宙图片。 图 3.9 文件管理 3.2.3 功能体验 功能体验UI分为两层呈现。外面一层同样用一个继承ListActivity的类来实现,在list空间里排布好每个图标和文字的位置,这里要用到ImageView控件添加图片。内层则是一个介绍体验层,这层的总体排布用LinearLayout的垂直分布就可以完成。添加Button按钮实现用户体验功能。 3.2.4 功能查看 这个界面完全是文字的排布,同样用ListActivity加以LinearLayout垂直型布局就可以完成。 3.2.5 功能设置 功能设置UI为用户可操控界面,所以要使用继承PreferenceActivity的类来完成相应的功能,此类是Android专门用来做UI设置界面用的,所以这个类中方法的应用也相对方便,但其布局文件与众不同,需要在res文件中新建个XML文件进行单独管理。其布局空间类型主要分为3大类AppWidget Provider、PreferenceScreen和Searchable,其中最常用的是PreferenceScreen,在这里又包含CheckBoxPreference、EditTextRreference、ListPreference、Preference、RreferenceCategory、PreferenceScreen和RingtonePreference7个控件[8]。我们的UI设置界面就用PreferenceScreen来完成。 7 / 77 . 3.3 Service设计 手机防盗应用软件在实际应用过程中一定是常驻后台的软件,所以不管用户是否打开软件,只要是开启了防盗功能,那此软件就会一直在后台运行,出于这样的考虑,我们就必须引进一个强大的后台支持,那就是Service既后台服务。 3.3.1 数据库存储服务 在Android系统中,用于保存数据有3种方式:SQLite、SharedPreferences和File。 SQLite是一种嵌入式系统中很常见的数据库,而且所有的数据都储存在一个文件中,便于迁移。SQLite有见解的SQL访问界面、相当快的速度,而且仅占用相对其他数据库少量的内存空间。在Android平台上,SQLite库可以用来存储应用程序中使用到的数据,还可以通过定义Content Provider等方式,来让其他应用程序也可以取用其中的数据[9]。 SharedPreferences是以键值对来存储应用程序的配置信息的一种方式,它只能存储基本数据类型。一个程序的配置文件仅可以在本应用程序中使用,或者说只能在同一个包内使用,不能在不同的包之间使用。实际上sharedPreferences是采用了XML格式将数据存储到设备中,在DDMS中的File Explorer中的/data/data//shares_prefs下。 File是一种文件存储方式也是一种较常用的方法,在Android中读取/写入文件的方法,与Java中实现I/O的程序是完全一样的,提供了openFileInput<>和openFileOutput<>方法来读取设备上的文件。 具体问题具体分心,根据我们的需要与要求,本程序最终选定用SharedPreferences来存储我们的数据。我们将用户设置的安全密码、安全手机号、防盗功能开关状态、SIM卡的IMSI码等信息以键值对的形式存入其中进行保存。一个Value对应一个Key值,如图3.10所示,Key值便是我们所保存的数据信息,这样的保存方式既快捷又准确。 图 3.10 数据库存储方式 3.3.2 监听按钮事件服务 监听器是Android设计的一种监听模式,当用户执行了某些动作时,需要系统对这些动作做出相应的反应,那么这时就需要监听器来捕获这些来自用户的信息,将其传递给系统再做处理。 在我们的软件中将会运用大量的监听器,其中包括监听用户点击按钮事件、监听开机广播事件、监听短信广播事件等。 监听按钮事件,是将每个按钮绑定上一个监听器,用lickListener<>方法来实现,当触发相应的监听器后我们就可以执行我们想要的操作了。 3.3.3 开机启动和短信广播服务 防盗应用开启后会在第一时间对手机的SIM卡进行检查,判断时候更换。那么这种监听开机需要另一项Android机制的支持来完成——广播机制。 8 / 77 . 在 Android 里面有各种各样的广播,比如电池的使用状态,的接收和短信的接收都会产生一个广播。图3.11就是一张广播的运行机制原理图。 图 3.11 Android广播机制 各种广播在Android 系统中运行,当系统/应用程序运行时便会向 Android 注册各种广播,Android 接收到广播会便会判断哪种广播需要哪种事件,然后向不同需要事件的应用程序注册事件,不同的广播可能处理不同的事件也可能处理相同的广播事件,这时就需要Android 系统为我们做筛选。 本软件就利用开机广播和短信接收广播来判断手机状态和控制手机。 3.3.4 GPS服务 对于GPS我想大家现在都很了解,至少不会陌生,一般情况下每个装载GPS的设备都会由3颗卫星进行定位,在需要时可将设备所在的位置信息发送到GPS上,例如返回的经纬度,有了这些位置信息我们便可进行需要的操作[10]。 在本应用中将会运用Android手机的GPS定位系统,为我们获取手机的当前位置,便于用户找回丢失的手机 3.3.5 私人数据的管理 当用户的手机丢失后恐怕最担心的就是自己私人信息的外露,出于此考虑,本软件将通过继承IntentService的类,对用户的通讯录、媒体图片进行备份并向安全手机发送,同时将原有数据删除,以防止不法分子的非法企图。 4 手机防盗应用方案的实施 按照手机防盗应用技术的设计理念,我将从UI入手,在做完界面的基础上组合、衔接并加入相应的功能,最后通过Service实现后台监听、储存、处理等功能。 在实现这些功能之前我们需要先搭建Android开发环境,其具体操作流程见附表二。 4.1 UI的实现 在Android系统中,UI的构建主要都由Activity类来完成。为了开发方便,Android又构造了多个继承Activity类的子类。其中在我们的软件里用到了ListActivity和PreferenceActivity两个子类和Activity本身。 4.1.1 Activity 要使用Activity以及其子类首先要知道Activity的生命周期,只有知道其生命周期的顺序才能控制好界面的显示。图4.1为Google官方给出的Activity生命周期流程图。 9 / 77 . 图 4.1 Activity生命周期 在本软件中有8个UI直接通过继承Activity类构成,他们的应用方法XX小异,我就拿其中最复杂的初始化界面来介绍。 初始化界面的整体设计流程图如图4.2所示。 图 4.2 初始化UI流程图 ➢ .java文件: 首先新建一个继承Activity的类First Public class First extends Activity{} 在此类里面对UI界面进行编辑 以下为关键代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 //覆写onCreate方法 public void onCreate //绘制UI界面 setContentView<>; //用findViewById的方法声明并得到Button控件 Button bt_sure = //用setOnClickListener方法绑定Button监听器,获取用户点击按钮事件 bt_lickListener //用if……else if……else if语句对用户设置信息进行判断 if //用xt<>方法做出相应提示 xt<, "密码不能为空", _LONG>.show<>; else if…… else{ //建立数据库编辑对象 Editor editor = <>; //储存安全密码到数据库 ing<"password", Str_password1>; //提交改动到数据库并保存 editormit<>; //创建intent对象 Intent intent = new Intent<>; //指明跳转Activity ss<, >; //开启要跳转的UI ctivity 图 4.3 layout布局控件示意图 ➢ 文件: 为Activity提供布局支持的layout文件是UI如何显示的控制中心,这个文件里的控件属性决定了控件的显示位置,图4.3是为First提供布局控件的layout的示意图,其主要代码如下: 10 / 77 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 //第一行定义了布局文件所链接数据库的版本以及支持的语言,"utf-8"为中文。 //采用LinearLayout绝对布局的orientation属性定为vertical既垂直布局,第//一行属性为Android固定格式,我们不用过多研究 android:orientation="vertical" > //在布局文件中放进文本框并定义相关属性 //嵌套绝对布局的水平布局 //嵌套相对布局 ➢ 文件: Android中设立了一个统一管理文件,这个文件可以理解为Android的一个注册表文件,在这个文件中,我们可以声明我们自己定义的权限。如果所用的组件需要权限但没有在这个文件注册,应用程序就会无法正常运行。任何一个Activity类都是需要注册的,所以本应用的 主要代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 //注册接受开机广播权限 //注册发送短信权限 //注册获取具体地址权限 /> //请求Activity显示 android:icon="drawable/dun" android:label="string/fangdao" > android:name=".Main" android:label="string/fangdao" android:clearTaskOnLaunch="true" > //通过intent-filter设置首显Activity 11 / 77 . 22 23 24 25 26 27 28 29 30 31 32 33 34 //注册广播接受类 android:name="_COMPLETED"> //注册服务类 4.1.2 ListActivity ListActivity 直接继承于Activity,是手机基本应用中最常用的一类应用程序。ListActivity用来在屏幕中显示一个列表,当点击其中的某一列时,可以触发一些操作。我们通过设置一个onListItemClick函数,来得到用户正选择了哪一列的信息,并做后续处理。使用了ListActivity类后,如果整个屏幕上只需显示一个列表,我们甚至可以把setContentView一行注释掉,不用定义列表的XML说明文件。因为ListActivity类已经默认绑定了一个ListView〔列表视图界面组件。图4.4就是一个典型的ListView示意图。 图 4.4 ListView示意图 在本软件中,UI主层和UI功能体验层的列表视图就是通过直接继承ListActivity这个类得到的。在继承ListActivity的类中要想显示列表内容就必须要调用setListAdapter 图 4.5 体验功能UI流程图 ➢ Java文件: 1 2 3 4 5 6 7 8 //首先我们的体验层要继承ListActivity public class Tiyan extends ListActivity //在这里设置各功能对应的数值 private static final int dingwei = 0; //定位手机 private static final int xiaohui = 1; //销毁数据 private static final int suoding = 2; //锁定手机 private static final int baojing = 3; //发报警音 private static final int huanka = 4; //换卡短信通知 12 / 77 . 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 //这里我们需要在layout文件中设置两个布局文件,一个用于主框架,另一个是为//list单独建立的,专门摆放list中的控件,下面这句代码就是主框架 setContentView<>; //建立一个HashMap放进 ArrayList中 ArrayList =new ArrayList //分别生成对象,以map1为例,后面4组方法相同 HashMap //向Map中对应位置装入数据, <"tiyan", "定位手机">; <"jianjie", "获取手机当前位置,便于您找回">; <"img", i>; //将Map加入list,这样数据就存放在列表当中啦 //生成Adapter,并实现通过setListAdapter<>方法实现list SimpleAdapter listAdapter = new SimpleAdapter new String[]{"tiyan","jianjie","img"}, new int[]{,,}>; setListAdapter //覆写onListItemClick<>方法获得用户点击事件 Override protected void onListItemClick // TODO Auto-generated method stub ItemClick Intent intent = new Intent<>; // ra<"textIntent","123">; //"防盗功能体验"界面 if { ss<,>; ctivity } else if<> …… } 图 4.6 ListActivity中layout框架 ➢ 文件: 图4.6展示了在ListActivity中两个layout的布局框架,以下为代码分析: ➢ 文件: 在文件中只有一个ListView控件 1 2 13 / 77 . 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //这里注意ListView的id一定为list,这是android系统中默认的id,不能自拟。 android:id="+id/android:list" // scrollbars属性为选择滚动条方向,这里我们定位垂直方向。 android:scrollbars="vertical" /> ➢ 文件: 在文件中采用相对布局RelativeLayout,以方便控件的摆放 // ImageView为图片View,是用于添加图片的控件 //一下是两个文本信息,就是实际列表中要显示的值 4.1.3 PreferenceActivity 在Android中有一个Preference类,用于手机的属性设置。因此当我们在界面上做设置的时候自然就会想到Activity+Preference的组合,前者用于界面的构造,后者用于设置数据的存放。不过虽然做法没错,但是会比较繁琐,因为每个设置选项都要建立与其对应的Preference。当然Android的设计者也考虑到了这点,在系统中为我们提供了一个专门用于开发界面设置的类PreferenceActivity,这个类完美结合了Activity与Preference,很大程度的方便了我们的开发,因此我们的UI功能设置界面就是通过继承此类的类来实现。 继承PreferenceActivity的UI设置界面的java文件无需过多的编程代码,因为在PreferenceActivity上做的任何设置,系统都会自动以键值对的方式储存到数据库里,当我们需要这些数据的时候,便可以直接从数据库里调用。所以我们只需要在布局文件中按需求添加控件就可以了。 PreferenceActivity的布局文件有些特殊,需要在res文件夹下新建一个xml文件夹用于单独存放此类控件和布局属性,如图4.7所示。 图 4.7 Preference的布局文件 其文件构架如图4.8所示。 图 4.8 文件构架 控件属性在本软件中的应用如图4.9所示。 图 4.9 文件属性构架 其代码就是对属性进行相应配置即可如android:password="true"等,这里就不做详细介绍了,具体代码请看附录二。 14 / 77 . 4.1.4 Dialog Dialog是android开发过程中最常用到的组件之一,它包括以下几种类型: 1. 警告对话框:Alertialog 2. 进度对话框:ProgressDialog 3. 日期选择对话框:DatePickerDialog 4. 时间选择对话框:TimePickerDialog 5. 自定义对话框:从Dialog继承 Dialog的创建方式有两种: 一是直接new一个Dialog对象,然后调用Dialog对象的show和dismiss方法来控制对话框的显示和隐藏。 二是在Activity的onCreateDialog 区别在于通过第二种方式创建的对话框会继承Activity的属性,比如获得Activity的menu事件等。 本软件就采用第二种方法用于显示弹出的对话框。其程序流程图如图4.10所示。 图 4.10 Dialog流程图 ➢ java文件关键代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 //首先先创建一个Dialog函数 private void putPWDialog<> { //渲染布局文件 LayoutInflater inflater = View view = e //生成Dialog对象并进行设置 r builder = new r le<"输入密码">; //显示Dialog界面 w showputPWDialog = <>; <>; //监听确定按钮 btn_lickListener //信息核对提示 if<<>.equals<"">> { else if<<>.equals else{} //监听退出按钮 btn_lickListener //完全退出程序 public void onClick tance<>.exit<>; } 15 / 77 . 经过大量的调整、核对以及调试,我们的UI界面就这样完成啦。到此为止把我们的软件安装到手机上就可以进行所有界面的切换了。 4.2 由Sever支持的Function实现 有了完整的UI,我们就可以在Function里实现这些UI对应的功能。对于任何一个软件来说,无论它有什么样的UI,人们最终想要获得的还是软件的功能。所以,只有Function的完美实现才能体现出一个软件的真正价值。 4.2.1 广播机制服务 之前已经介绍了Android系统中广播机制的概念,这里就主要说明在本软件中所用到的3种广播——开机完成广播、服务状态广播和短信接收广播。 开机完成广播和服务状态广播用于监测SIM卡的状态改变。当用户开机完成时,系统就会向接收开机完成广播的应用软件发送开机完成广播,告诉他们已完成开机动作,此时软件就可以在接收此指令后做出自己需要的动作,例如开机运行的软件就都需要接收开机完成广播。服务状态广播也是同样的原理,当手机检测到信号后就会由系统向所有应用发送服务状态改变的广播。 短信接收广播是当手机接收到短信时Android系统向应用程序发送的一种广播。手机系统中自带的有些功能都要通过这种广播来完成动作。例如手机收到短信时会产生音乐和振动等状态,这就是由短息模块在接收到系统短信接收广播后作出的动作。 为了接收来自系统的广播,Android为开发者提供了一个专门用于接收广播的类既BroadcastReceiver类,本软件就通过继承此类实现接收所有广播。在Android中光有接收的类还不行,要想让系统把广播发送到你的应用程序还必须在文件中进行权限注册,让系统知道你需要接收广播并给你开放ROOT允许你使用才行。下面代码为本应用所有的权限注册代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /> /> /> 在本软件中远程控制手机就是通过此短信广播接收机制实现的。当系统收到短信后16 / 77 . 会向需要接收广播的应用发送短信广播,本应用接收广播后就可根据短信内容做出相应的动作了。其服务程序流程图如图4.11所示。 图 4.11 SMS服务流程图 短信接收后台服务关键代码解析如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //创建SMSReceivedBroadcastReceiver类继承BroadcastReceiver类实现接收短信广播 publicclass SMSReceivedBroadcastReceiver extends BroadcastReceiver { //覆写父类onReceive方法执行动作 publicvoid onReceive // 检测防盗保护是否开启 if //通过msgs[i].getDisplayOriginatingAddress<>方法得到来源短信号码 //对比是否为安全手机号 if<<>.equals<"+86" + safenumber>>{} elseif<<>.equals<"12520" + safenumber>>{} elseif<<>.equals // 1.执行GPS定位 if // 2.执行锁定手机 elseif // 3.执行发报警音 elseif // 4.执行销毁数据 elseif } 4.2.2 换卡短信通知 本应用在开机完成后首先接收系统发出的开机完成广播,这时软件就会在后台开始检测SIM卡的IMSI码信息,如果此信息与原保存的IMSI码不一致,则说明手机处于非安全状态。待手机检测到信号,可执行移动服务的时候,服务状态广播就会向手机所有应用发送此广播。当本应用接收到此广播后就会立即向安全手机号发送SIM卡被更换的报告。其服务效果如图4.12所示。 图 4.12 开机检测SIM卡信息流程图 开机检测SIM卡程序主要代码分析如下: 1 2 3 4 5 6 7 8 //创建一个用于开机接收广播的类BootCompleteReceiver publicclass BootCompleteReceiver extends BroadcastReceiver { //覆写父类中的onReceive执行动作 publicvoid onReceive //判断是否开启防盗保护和换卡通知 if //通过getSubscriberId<>方法提取SIM卡IMSI号 String IMSI = scriberId<>; 17 / 77 . 9 10 11 12 13 14 15 16 17 18 19 20 //判断是否与安全IMSI号相等 if<<>.equals return; } //不等则后台向安全手机号发送短信 else { SmsManager manager = ault<>; List safeIMSI + " 的手机,SIM已被更换,更换的IMSI码为:" + IMSI>; for xtMessage 4.2.3 定位手机 Android系统可通过手机的GPS模块为我们提供当前手机的位置信息既经纬度。然后我们再通过向服务器发送地址请求的方式得到手机的具体位置既街道等。其具体实现流程图如图4.13所示。 图 4.13 GPS定位流程图 GPS定位的主要代码分析如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 //建立一个GPS类继承Service public class GPS extends Service{ //创建一个getGPS方法用于获取GPS地址 public void getGPS //得到LocationManager对象 LocationManager locationManager = //获取指定时间指定偏移距离地址信息 tLocationUpdates<_PROVIDER, 0, 0, new TestLocationListener<>>; } //实现LocationListener接口 public class TestLocationListener implements LocationListener{ //当用户位置发生改变时获取经纬度 public void onLocationChanged //指定请求服务器域名 String url = "://apis/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=false"; //创建一个Client对象 Client Client = new DefaultClient<>; //向指定的URL发送请求 18 / 77 . 23 24 25 26 27 28 Response response = e //取得服务器返回的响应 Entity entity = ity<>; //生成Gson对象 Gson gson = new Gson<>; //解析Gson数据并存入testResult testResult = on 有了提供具体位置的GPS服务类,我们只需将信息通过SMS发送到指定安全号码即可远程获得手机的具体位置了。 4.2.4 数据销毁 为了避免隐私泄露,我们需要创建一个专门的类用于处理我们的用户信息,此类应具有备份和删除两个功能。对于用户的隐私文件我们把焦点主要放在联系人和媒体上。因此,我们需要连接并提取联系人和媒体的资料,并拥有删除这些文件的权限方可达到目的。其实现流程图为图4.14所示。 图 4.14 销毁数据流程图 其主要代码分析如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //创建创建TaskService类继承IntentService类 public class TaskService extends IntentService { //覆写父类onHandleIntent方法 protected void onHandleIntent //通过Extra方法提取选择功能 int code = Extra<_TASKCODE, -1>; switch case DE_BACKCONTACTS: Log.i<"guard", "备份联系人">; backContacts<>; break; case DE_DELETECONTACTS: Log.i<"guard", "删除联系人">; deleteContacts<>; break; case DE_DELETEMEDIAS: Log.i<"guard", "删除媒体信息">; deleteMedia_Images<>; break; } 19 / 77 . 4.2.5 锁定手机 当收到锁定手机的指令后,要求手机立刻进入锁屏状态,只能在屏幕上输入安全密码,密码验证通过后手机会恢复正常,要是密码错误则会禁止用户任何操作,直到密码输入正确为止才能使用。其实现效果如图4.15所示。 图 4.15 锁屏流程图 根据程序流程,所以用户一定要在安装完本应用后实现一次锁屏获得ROOT权限后方可远程控制锁屏功能实现。以下为功能实现分析: DevicePolicyManager:顾名思义,这个类的作用是管理设备。通过这个类,我们可以实现屏幕锁定、亮度调节甚至是恢复出厂设置等功能。 DeviceAdminReceiver:这个类的父类是BroadcastReceiver,通过其OnReceive方法可以根据不同的Action执行不同的动作。 这个程序的开发过程大致如下: 要想使用DevicePolicyManager中的方法,首先要定义一个Component。然后通过管理这个组件来启动一个DeviceAdminReceiver。 注册一个广播,用于监听权限的变化,代码在文件中: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 2 3 4 5 6 android:name=".LockScreenAdmin" android:label="string/app_name" android:description="string/app_name" //表示此功能所需的权限 android:permission="_DEVICE_ADMIN"> //表示这个动作的跳转界面 android:resource="xml/lock_screen_admin" /> 其中,android:resource="xml/lock_screen_admin"所指向的内容如下: xmlns:android=""> 实现一个继承自DeviceAdminReceiver的类,实现必须的方法。这个类基本不用写代码,在此略过不表。 这段代码用来在第一次运行的时候激活component,只要激活一次之后,这个component就会一直是激活的。使用startActivityForResult<>可以在onResult方法中调用lockNow<>来锁屏,当不是第一次运行的时候,直接调用lockNow<>锁屏。 20 / 77 . 1 2 3 4 5 6 7 8 9 10 11 12 if w<>; finish<>; } else {// 第一次运行程序 Intent intent = new Intent< _ADD_DEVICE_ADMIN>; ra<_DEVICE_ADMIN, mComponentname>; ra<_ADD_EXPLANATION, "One key lock screen need to active">; startActivityForResult } 4.2.6 发报警音 发报警音的功能实现比较简单,只需要在收到指令后在后台开启影音即可,主要代码如下所示: 1 eamMaxVolume<_MUSIC>;eam2 Volume<_MUSIC>; 4.2.7 数据库存储应用 由于本程序正常工作时运行在后台,所以要运用数据库存放数据。这里数据库的运用在每个单元功能内都必不可少,是否开启防盗功能、是否是第一次启动应用程序、安全手机号、安全密码等数据都交由数据库保存。以安全密码为例在程序中运用代码如下所示: 1 2 3 4 5 6 7 8 9 10 11 //连接数据库生成称对象 SharedPreference sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; //提取安全密码运用 String safenumber = ing<"safenumber", "">; //生成Editor对象 Editor editor = <>; //修改更新数据 ing<"Ssafenumber", Tsafenumber>; //提交数据并保存 editormit<>; 21 / 77 . 5 手机防盗应用测试 上安装本应用软件,另一台用于发送指令。 5.1 防盗应用初始化 如图5.1所示。 图 5.1 初始化设置 在设置界面里开启所有功能。 关闭此防盗应用,退回到手机主界面。 5.2 手机定位功能测试 发送指令:123456#dingwei,〔因为是模拟器,所以需要预先在DDMS里给。5.2所示。 图 5.2 定位功能 由于是模拟器演示,模拟器不支持中文,所以现在返回的是一些乱码,到真机上就能看懂了。 5.3 换卡短信通知功能测试 接下来我们进入DDMS,在Devices窗口里选中emulator-5554,然后在File Explorer窗口中进入data/data/o文件夹,如图5.3所示。 图 5.3 换卡通知date 在shared_prefs文件夹中找到o_文件并将其倒出。如图5.4所示。 图 5.4 数据库位置 这个文件就是数据库文件,将其SIM卡的IMSI号码更改,然后倒入源地址,这样就能模拟换卡的状态了。数据库IMSI码更换前后如图5.5和图5.6所示。 图 5.5 数据库IMSI码更换前 图 5.6 数据库IMSI码更换后 5.4 锁屏功能测试 :123456#suoding 5.7所示。 图 5.7 锁屏功能 22 / 77 . 5.5 销毁数据 由于模拟器没有SD卡,所以本功能只能在真机上测试,其测试方法同样是靠短信指令实现,测试后查看SD卡数据及手机通讯录和媒体数据已全部清空。既销毁数据功能实现。 5.6 发报警音 由于模拟器也无法播放媒体,所以也只能真机测试,由于本功能属于后台运行,真机测试时,当收到指令立即以最大音量报警,既发报警音功能实现。 6 手机防盗应用说明 首先开启防盗应用软件进入初始化界面,在第一个文本框输入安全密码,第二个文本框输入确认密码,两次密码输入必须符合提示要求,否则将不被软件认可。在下面的文本框输入安全手机号码,此号码建议输入亲友,在输入非法号码时,软件将给出相应提示并允许用户重新输入。 手机SIM卡被更换:您向被盗手机发送了锁定手机指令以上两种情况,手机防盗将为您锁定被盗手机,防止别人使用您的手机或查看隐私信息。 手机定位:手机被盗后,可以用任意手机发送定位手机指令到被盗手机,获取手机当前位置,帮您找回手机。定位手机成功后,将会发送短信告知您手机的位置。 *定位手机指令:dingwei#防盗密码 销毁数据:手机被盗后,用安全手机号发送销毁指令到被盗手机,可彻底销毁手机数据,保护隐私不被泄露。销毁的数据包括:通讯录、短信、照片及SD卡的其他数据。特别提醒:销毁数据指令必须使用安全手机号发送。 *销毁数据指令:xiaohui#防盗密码 锁定手机:当手机收到锁定手机指令后会立即锁屏,只有输入正确的安全防盗密码才可解锁手机 。 *锁定手机指令:suoding#防盗密码 发报警音:发觉手机被盗后,可用任意手机发送报警指令到被盗手机。这时被盗手机将发出最大音量的报警声〔即使是静音模式,帮助您快速找到手机。 *发报警音指令:baojing#防盗密码 用户可在设置界面对初始化设置的安全密码和安全手机号进行修改,并可设置防盗功能开关、换卡通知开关以及换卡锁定开关。 结论 在这个高度信息化的时代,手机的丢失总会给人带来很多烦恼,但最让人烦心的是手机中存储的多年好友通讯录、记载着岁月的照片、视频等私人数据都一并丢失。本文所设计的软件就是专门为解决此问题而设计的。 23 / 77 . 本文结合用户手机丢失导致私人信息不安全的问题,总结手机丢失给用户带来的后果,然后根据需求设计软件。本软件基于Android系统平台进行设计,所以文章从软件的UI入手,对比并采用市场上最受用户喜欢的列表式界面设计,应用继承ListActivity的类完美实现。在设置功能按钮的设置界面采用Android系统级UI专用设置类PreferenceActivity参与设计,并以最方便的排版方式实现设置层UI。做好显示后应用Intent传递各UI间的数据,并在关闭软件后将必要的数据存储在SharedPreferences数据库中。在完成整个UI设计后文章逐个介绍每个功能的实现方法及过程。其中运用GPS技术定位手机,并可通过Android系统广播机制,控制手机向指定手机发送当前手机具体位置。要想通过短信控制被盗手机,就要知道被盗手机的手机号码,为此,文章从手机号码来源入手分析,总结得出要想知道当前手机号,必须要获得此手机SIM卡的IMSI码来确定唯一的SIM卡,拥有IMSI码号后便可到移动公司查到当前SIM卡的手机号进而才可实现功能。由问题又引出亲的问题,接下来就要解决如何获取SIM卡IMSI号的问题,这里本章介绍了如何运用Android广播机制中的开机广播和信号广播以及短信广播来监听手机SIM卡状态。在软件检测到SIM卡被更换时,会立即将当前SIM卡信息传递到SMS机制并向指定手机发送指令要求信息。接下来本章具体讲述了在能远程向被盗手机发送指令的情况下如何实现锁屏、销毁隐私数据以及报警等其他防盗功能。 所有功能的实现都在后台完成,这样才能在让非法分子在毫无察觉的情况下绳之以法。本文具体介绍了后台服务的Service,所用到的具体数据都来源于Service服务。GPS的定位、用户隐私数据的备份发送与销毁等功能的实现都是因为拥有强大的后台Service支持才得以实现。 经过大量实验调试,最终本软件实现了所有防盗功能。当安有此防盗软件手机丢失时,后台工作的软件会自动检测到不安全状态,待安全手机号收到目标手机当前手机号后便可通过防盗指令控制被盗手机锁屏并以最大音量发报警音,在不法分子还没来得反应的时候,公安人员已经按照软件所提供的GPS定位地址将其制服并拿回属于用户的手机。如果不法分子为了消赃毁坏了手机,那我想在手机被盗的第一时刻用户就已经把自己的重要信息备份出来了,再无忧患所言。 致谢 经过几个月的努力,本人的毕业设计"基于Android系统的手机防盗应用"以完美完成。作为一个本科生的毕业设计,由于经验的匮乏,难免有许多考虑不周全的地方,如果没有导师的督促指导,以及一起工作的同学们的支持,想要完成这个设计是难以想象的。 首先要感谢的是我的导师刘军华老师,在我当初想要以Android系统应用作为我毕设题目的时候,给了我很大的鼓励与支持。本来在学校做毕设的同学,毕设题目是学校的老师指定好的,学生需在所有题目中选择一个作为自己的毕设来做。我学的专业是电子信息工程,所学的知识以硬件为主,因此所有的题目都是以硬件为主的,特别是我导师刘军华的题目,基本都是以ARM研究为主的。但是我对Android系统这个纯软件方向比较感兴趣,就想做个Android的应用作为自己的毕设,所以很是为难。但当我和刘老师说了我的想法后,他没有反对,反而非常支持,并想给我介绍到一家做Android的公司去学习并完成毕设。而后又帮我设定并确定毕设要完成的任务,如我愿的以"基于Android系统的手机防盗应用"项目做为了自己的毕业设计。也只有老师这样的抉择才能实现我现在的毕业设计。在这里对刘老师深表感谢! 对于Android系统我属于白手起家,甚至连Java语言都不是很扎实,所以一上来就像做应用是根本不可能的事。我的同学对Android有一些了解,知道我要做Android系统24 / 77 . 应用的毕设后主动帮我找资料,介绍Android的个大论坛,以及其编译环境等,给初学者的我指明了学习的方向,少走了很多弯路,非常感谢你们! 关于我对Android系统学习影响最大的就是mars老师了,mars老师是Android教学视频的老师,虽然他不认识我,但我几乎说有的Android系统知识都来源于mars老师的课程。mars老师不仅Android系统讲得好,而且还为我这样的初学者专门做了一系列Java4Android的视频很好的弥补了我的Java基础不足的缺陷。这里郑重感谢网络教师mars老师,感谢您的教导,祝您的教育事业越办越好! 还不能忘了感谢我们最常用的百度和Google公司,他们的文库为我提供了巨大地资料,决绝了我很多问题。还有Android联盟里的同志们,有了你们的帮助才使我少走弯路,在我不理解的时候你们耐心讲解,虽然我们并不知道彼此的容颜,但我却深知你们那份乐于助人的心。真心的感谢您们,祝你们工作顺利! 感谢我的父母,在我在家做毕设的时候,他们耐心的为我做饭,尽最大努力帮我排除一切影响因素,儿子在这里谢谢您们!祝您们身体健康! 一路走来,要感谢的人太多了,是你们的帮助才有我现在的成就,谢谢你们! 参考文献 1 张浩,基于Android平台手机防盗追踪功能的实现[J].XX理工大学信息工程与自动化学院,20XX8月17日. 2 盖锁林,王世江.Google Android开发入门指南[M].第二版.人民邮电出版社,20XX2月. 3 吴亚峰,苏亚光. Google Android应用案例开发大全[M].人民邮电出版社,20XX9月1日 4 胡辛征,高洪霞.21天学通Java[M].第二版.电子工业出版社,20XX7月. 5 E2EColud工作室.深入浅出Google Android[M].人民邮电出版社,2009. 6 林城.Android2.3应用开发实战[M].机械工业出版社,20XX6月1日. 7 李刚.疯狂Android讲义[M].电子工业出版社,20XX6月22日. 8 吴亚峰,索依娜,百纳科技.Android核心技术与实例详解[M].电子工业出版社,20XX10月1日. 9 余志龙,王世江.Google Android SDK开发范例大全[M].人民邮电出版社,20XX6月1日. 10 靳岩,姚尚朗.Android开发入门与实战[M].人民邮电出版社,20XX7月1日. 11 的个人论坛[EB/OL]., 20XX9月10日/20XX3月5日. 12 d视频教程[CD].mars视频,20XX11月/20XX3月. 13 4Android视频教程[CD].mars视频,20XX11月/20XX3月. 14 d之PreferenceActivity[J/OL].CSDN,20XX1月16日/20XX4月9日. 15 ew and CheckBox[J/OL].ITCYC,20XX9月30日/20XX4月20日. 16 ew加在性能优化ViewHolder[J/OL].CSDN,20XX12月20日/20XX5月3日. 17 d ListView详解[J/OL].android diordna,20XX12月19日/20XX5月15日. 18 Sayed Android 3[M].Apress,2011. 19 Donn d Application Development for Dummies[M].HUNGRY 25 / 77 . MINDS,2010.11.22. 20 Mark ing Android 3[M].Apress,2011. 21 Ed Burnett,Susannah Davidson , Android: Introducing Google's Mobile Development Platform[M].Pragmatic Bookshelf,2011. 附录一 图片: 附录二 一 相关下载 <1> java JDK下载: 进入该网页: 如下图: 选择 Download JDK 只下载JDK,无需下载jre. <2>eclipse下载 进入该网页: 如下图: 我们选择第一个<即eclipse IDE for java EE Developers> <3>下载Android SDK 说明: Android SDK两种下载版本,一种是包含具体版本的SDK的,一种是只有升级工具,而不包含具体的SDK版本,后一种大概20多M,前一种70多M。 <1>安装jdk 6u19:安装完成即可,无需配置环境变量 26 / 77 . <2>解压eclipse:eclipse无需安装,解压后,直接打开就行 <3>解压android sdk:这个也无需安装,解压后供后面使用 <4>最终有三个文件夹,如下图: 三 Eclipse配置 1 安装android 开发插件 <1>打开Eclipse, 在菜单栏上选择 help->Install New SoftWare 出现如下界面: 点击 Add按钮,出现如下界面 输入网址: 名称: Android <这里可以自定义> 点击OK,将出现如下界面 点击 Next按钮 ,出现如下界面: 点击Next按钮,出现如下界面: 选择 I accept the terms of the license agreements 点击Next,进入安装插件界面 安装完成后,出现如下界面 点击Yes按钮,重启Eclipse 2 配置android sdk <1>点击菜单window->preferences,进入如下界面 选择你的android SDK解压后的目录,选错了就会报错,这个是升级工具,目前还没有一个版本的SDK 〔2升级SDK版本,选择菜单 window->Android sdk and avd manager 出现如下界面 选择update all按钮,出现如下界面 选择左边的某一项,点击accept表示安装,点击reject表示不安装,我这里只选了SDK 2.1 和samples for api 7 , 自己可以任意自定义,确定后,选择install按钮,进入安装界面如下: 安装完成如下: <3>新建AVD 点击New按钮后,进入如下界面: 名称可以随便取,target选择你需要的SDK版本,SD卡大小自定义,点击 Create AVD,得到如下结果 如上显示创建AVD完毕 附录三 源代码: 27 / 77 . src文件java代码: 1. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package o; import ty; import ; public class Baojing extends Activity{ Override protected void onCreate // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity setContentView } } package o; import ; import astReceiver; import t; import ; import Preferences; import ager; import onyManager; public class BootCompleteReceiver extends BroadcastReceiver { SharedPreferences sp; TelephonyManager tm; Override public void onReceive sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; tm = temService boolean isprotect = lean<"protect", false>; 28 / 77 2. . 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 1 2 3 4 5 6 7 8 9 10 11 12 13 boolean issendID = lean<"sendID", false>; n<"开机">; n<"isprotect------->" + isprotect>; n<"issendID------->" + issendID>; if String safeIMSI = ing<"IMSI", "">; String safenumber = ing<"safenumber", "">; //IMSI String IMSI = scriberId<>; n<"subscriberId-------->"+IMSI>; if<<>.equals return; } else { //SmsManager SmsManager manager = ault<>; List + " 的手机,SIM已被更换,更换的IMSI码为:" + IMSI>; for xtMessage n<"已发送">; } } } else { return; } } } package o; import ty; import ; public class Chakan extends Activity{ Override protected void onCreate // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity 29 / 77 3. . 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 } } setContentView<>; 4. package o; import ty; import ; public class Dingwei extends Activity{ Override protected void onCreate // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity setContentView; } } package o; import ty; import ; import Preferences; import ; import ; import onyManager; import ; import kListener; import ; import xt; import ; public class First extends Activity{ boolean isFirst; SharedPreferences sp; TelephonyManager tm; /** Called when the activity is first created. */ 30 / 77 5. . 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 Override public void onCreate te setContentView<>; // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity sp = redPreferences<"o_preferences", MODE_WORLD_READABLE>; //IMSI tm = final String IMSI = scriberId<>; final EditText et_password1 = final EditText et_password2 = final EditText et_safenumber = Button bt_sure = Button bt_exit = bt_lickListener public void onClick String Str_password1 = et_t<>.toString<>; String Str_password2 = et_t<>.toString<>; String Str_safenumber = et_t<>.toString<>; if xt<, "密码不能为空", _LONG>.show<>; return; } else if 12>{ xt<, "请输入6-12位数字或字母的密码", _LONG>.show<>; return; } else if.equals xt<, "密码两次输入不一致,请重新输入", _LONG>.show<>; 31 / 77 . 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 return; } else if xt<, "手机号码不能为空_LONG>.show<>; return; } else if xt<, "手机号码错误_LONG>.show<>; return; } else{ // 建立数据库编辑对象 Editor editor = <>; // 储存当前手机IMSI到数据库 ing<"IMSI", IMSI>; // 储存密码到数据库 ing<"password", Str_password1>; // 储存安全手机号到数据库 ing<"safenumber", Str_safenumber>; // 改first值为false,再次打开应用时不进入此Activity lean<"first", false>; // 提交改动到数据库并保存 editormit<>; // 创建intent对象 Intent intent = new Intent<>; // 指明跳转Activity ss<, >; ctivity } } }>; bt_lickListener public void onClick // 调用exit方法完全退出 tance<>.exit<>; } }>; } } ", ", 6. 32 / 77 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package o; import edReader; import treamReader; import ; import sult; import ..Entity; import ..Response; import ..; import ..; import ..tClient; import e; import t; import ; import Preferences; import on; import onListener; import onManager; import ; import r; import ager; import ; public class GPS extends Service{ TestResult testResult; String Gsafenumber; SharedPreferences sp; int a = 0; public void getGPS a = 1; sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; Gsafenumber = ing<"Ssafenumber", "">; n<"----------->1">; LocationManager locationManager = n<"----------->2">; tLocationUpdates<_PROVIDER, 0, 0, new TestLocationListener<>>; 33 / 77 . 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 n<"----------->3">; } public class TestLocationListener implements LocationListener{ Override public void onLocationChanged n<"<<<1">; // TODO Auto-generated method stub n n if{ a = 0; String url = "://apis/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=false"; n<"<<<2">; //创建一个Client对象 Client Client = new DefaultClient<>; n<"<<<3">; String responseData = ""; n<"<<<4">; try{ //向指定的URL发送请求 Response response = e n<"<<<5">; //取得服务器返回的响应 Entity entity = ity<>; n<"<<<6">; BufferedReader bufferedReader = new BufferedReader InputStreamReader n<"<<<7">; String line = ""; n<"<<<8">; while< responseData = responseData + line; } n<"<<<9">; } catch tackTrace<>; } n<"<<<10">; 34 / 77 . 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 Gson gson = new Gson<>; n<"<<<11">; testResult = on n<"<<<12">; n SmsManager manager = ault<>; if List n<"已发送">; for xtMessage n<"<<<13">; } } else{ List testResult >; n<"已发送">; for xtMessage n<"<<<13">; } } } } Override public void onProviderDisabled // TODO Auto-generated method stub } Override public void onProviderEnabled // TODO Auto-generated method stub } Override public void onStatusChanged Bundle extras> { 35 / 77 . 130 131 132 133 134 135 136 137 138 139 140 141 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 } } } // TODO Auto-generated method stub Override public IBinder onBind // TODO Auto-generated method stub return null; } 7. package o; import ty; import ; public class Huanka extends Activity{ Override protected void onCreate // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity setContentView<>; } } package o; import ist; import p; import ialog; import tivity; import ; import Preferences; import ; import ; import Inflater; 36 / 77 8. . 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 import ; import kListener; import ; import xt; import ew; import Adapter; import ; public class Main extends ListActivity { boolean isFirst; boolean isDialog; SharedPreferences sp; AlertDialog showputPWDialog; private static final int tiyan = 0; //防盗功能体验 private static final int chakan = 1; //防盗指令查看 private static final int shezhi = 2; //防盗信息设置 /** Called when the activity is first created. */ public void getMaxVolume<>{ } Override public void onCreate te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity sp = redPreferences<"o_preferences", MODE_WORLD_READABLE>; isFirst = lean<"first", true>; isDialog = lean<"Dialog", false>; if Intent intent = new Intent<>; ss<, >; ctivity } else{ /////////////////测试区///////////// // Editor editor = <>; // lean<"first", true>; // editormit<>; //////////////////////////////////// 37 / 77 . 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 if putPWDialog<>; } else{ init<>; Editor editor = <>; lean<"Dialog", true>; editormit<>; } setContentView<>; } } private void init<> { /* Button bt_exit1 = bt_lickListener public void onClick // 调用exit方法完全退出 tance<>.exit<>; } }>;*/ ArrayList HashMap HashMap HashMap <"fangdao", "防盗功能体验">; <"jianjie", "了解手机防盗提供哪些功能">; <"img", >; <"jiantou", u>; <"fangdao", "防盗指令查看">; <"jianjie", "手机丢失后如何遥控操作">; <"img", >; <"jiantou", u>; <"fangdao", "防盗信息设置">; <"jianjie", "修改防盗密码、安全手机号等">; <"img", >; <"jiantou", u>; 38 / 77 . 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 SimpleAdapter listAdapter = new SimpleAdapter new String[]{"fangdao","jianjie","img","jiantou"}, new int[]{,,,}>; setListAdapter } private void putPWDialog<> { LayoutInflater inflater = View view = e final EditText et_password = Button btn_sure = Button btn_exit = r builder = new r le<"输入密码">; w showputPWDialog = <>; <>; btn_lickListener public void onClick String password = et_t<>.toString<>; String savedPassword = ing<"password", "">; if<<>.equals<"">> { xt<, "密码不能为空", _LONG>.show<>; return; } else if<<>.equals s<>; init<>; } else { xt<, "密码错误", _LONG>.show<>; 39 / 77 . 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 return; } } }>; btn_lickListener public void onClick tance<>.exit<>; } }>; } //选择菜单选项并进入选项页面 Override protected void onListItemClick { // TODO Auto-generated method stub ItemClick Intent intent = new Intent<>; n<"1">; if { ss<,>; ctivity } else if { ss<,>; ctivity } else if { ss<,>; ctivity } } } package o; import List; 40 / 77 9. 1 2 3 . 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 1 2 3 4 5 6 7 8 9 import ; import ty; import ation; public class MyApplication extends Application { private List private static MyApplication instance; private MyApplication<>{} //单例模式中获取唯一的MyApplication实例 public static MyApplication getInstance<>{ if instance = new MyApplication<>; } return instance; } //添加Activity到容器中 public void addActivity } //遍历所有Activity并finish public void exit<>{ for <>; } <0>; } } package o; import ty; import ; public class Paizhao extends Activity{ Override protected void onCreate 41 / 77 10. . 10 11 12 13 14 15 16 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 // TODO Auto-generated method stub te // 添加该Activity到MyApplication对象实例容器中 tance<>.addActivity setContentView } } package o; publicclass RunnableImpl implements Runnable { Override publicvoid run<> { // TODO Auto-generated method stub try{ } } } } n <5000>; 11. catch 12. package o; import ; import enceActivity; public class Shezhi extends PreferenceActivity{ Override publicvoid onCreate te } } addPreferencesFromResource<>; 13. package o; import ; 42 / 77 . 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import astReceiver; import t; import ; import Preferences; import ; import ager; import onyManager; public class Signal extends BroadcastReceiver{ SharedPreferences sp; TelephonyManager tm; Override public void onReceive sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; tm = temService boolean isprotect = lean<"protect", false>; //防盗开关 boolean issendID = lean<"sendID", false>; //发送IMSI boolean isBoot = lean<"Boot", false>; //开机启动 n<"信号">; n<"isprotect------->" + isprotect>; n<"issendID------->" + issendID>; n<"isBoot------->" + isBoot>; if Editor editor = <>; // 储存当前手机开关状态到数据库 lean<"Boot", false>; // 提交改动到数据库并保存 editormit<>; String safeIMSI = ing<"IMSI", "">; String safenumber = ing<"safenumber", "">; //IMSI String IMSI = scriberId<>; n<"subscriberId-------->"+IMSI>; if<<>.equals return; } else { //SmsManager SmsManager manager = ault<>; 43 / 77 . 48 49 50 51 52 53 54 55 56 57 58 59 60 61 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 List + " 的手机,SIM已被更换,更换的IMSI码为:" + IMSI>; for xtMessage n<"已发送">; } } } else { return; } } } package o; import astReceiver; import t; import ; import Preferences; import ; import anager; import sage; import onyManager; public class SMSReceivedBroadcastReceiver extends BroadcastReceiver { protected AudioManager mAudioManager; SharedPreferences sp; TelephonyManager tm; String Tsafenumber; int Inta; Override public void onReceive sp = redPreferences<"o_preferences", _WORLD_WRITEABLE>; tm = temService boolean isprotect = lean<"protect", false>; String safenumber = ing<"safenumber", "">; 44 / 77 14. . 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 // // // // // // // String password = ing<"paddword", "">; String IMSI = scriberId<>; n<"111">; Intent intent2 = new Intent<>; ss ervice n 检测防盗保护是否开启 if n<"开关开启">; Inta = 0; 接收短信并装入msgs Object[] object = byte[][] pdus = new byte[][]; for pdus[i] = } SmsMessage[] msgs = new SmsMessage[]; for msgs[i] = FromPdu } for oriAddress为短信来源号码 String oriAddress = msgs[i].getDisplayOriginatingAddress<>; n<"safenumber:"+safenumber>; n<"oriAddress:"+oriAddress>; n<"<>:"+<>>; n<<>.equals if<<>.equals<"+86" + safenumber>>{ n<"+86号码吻合">; Tsafenumber = "+86" + safenumber; Inta = 1; } else if<<>.equals<"12520" + safenumber>>{ n<"12520号码吻合">; Tsafenumber = "12520" + safenumber; Inta = 1; } else if<<>.equals n<"原号码吻合">; 45 / 77 . 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 // // // // } Tsafenumber = safenumber; Inta = 1; n if Editor editor = <>; ing<"Ssafenumber", Tsafenumber>; editormit<>; String body = msgs[i].getDisplayMessageBody<>; 定位 if n<"GPS定位">; abortBroadcast<>; GPS gps = new GPS<>; n<"---->gps">; } 2.锁定手机 else if abortBroadcast<>; } 3.发报警音 else if n<"报警">; abortBroadcast<>; n<"获取最大音量">; eamMaxVolume<_MUSIC>; eamVolume<_MUSIC>; n<"报警完成">; } 4.销毁数据 else if abortBroadcast<>; } } 46 / 77 {
{