【旅游讲解Android-APP的实现(论文)11000字】_第1页
【旅游讲解Android-APP的实现(论文)11000字】_第2页
【旅游讲解Android-APP的实现(论文)11000字】_第3页
【旅游讲解Android-APP的实现(论文)11000字】_第4页
【旅游讲解Android-APP的实现(论文)11000字】_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

-PAGEIV-旅游讲解Android-APP的实现摘要近年来,随着移动通信的发展和互联网对移动终端的普及,各种手机软件产业层出不穷。因为很多用户对景区不熟悉,造成不必要的人力、物力、财力浪费。游戏的过程具有很大的不确定性和不可预测性。实时、现场、随时随地获取信息是提高游戏体验质量的重要途径。本课题讨论的大连风景名胜区旅游解说助手正是基于这样的背景,其目的是让用户更全面、更方便地了解大连风景名胜区的实时信息,得到该风景名胜区旅游线路和重要浏览点的详细解说,以及周边其他相关景点的介绍,为游客提供更好的旅游体验。旅游讲解助手应用程序是基于AndroidStudio的移动应用软件。在主要实现过程中,利用百度API提供的web服务获取地图信息。在Baidu-API请求中引入城市名称、目的地等数据参数,查询旅游目的地和景点信息。通过SAXParser对XML数据文件进行解析,分析结果显示在UI界面上。关键词:Android;地图;旅游目录4404摘要 I42571绪论 1238671.1课题背景 1315681.2旅游系统的发展 1149311.3研究内容 26922系统关键技术简介 3260542.1Android系统简介 3252452.1.1Android特征 3107252.1.2Android系统架构 4191562.1.3Android应用组件 5130952.2MVP模式与MVC模式 6190673系统需求分析 7160063.1总体需求分析 7295723.2功能性需求分析 791203.2.1旅游讲解助手APP端功能需求分析 7242483.2.2旅游讲解助手PC端的功能需求分析 8248573.3系统环境需求 9156584系统概要设计 10176154.1系统结构设计 10189504.2前端功能模块的设计 11222354.3后端功能模块的设计 11184634.4数据库设计 1195925系统详情设计与实现 13206525.1登录与注册界面设计 13167105.1.1用户模块 1394795.1.2管理员模块 21298295.2景点信息模块设计 228915.3附近景点与附近美食模块设计 29218145.4用户模块设计 34162225.5景点添加模块设计 354427结论 387940参考文献 39PAGE2–PAGE15–1绪论随着移动互联网技术的快速发展和移动终端设备的普及,智能旅游迅速成为旅游业发展的重要途径。旅游业与信息产业逐步融合。全球信息浪潮推动了旅游业的信息化进程,全社会的信息化水平逐步提高,这也促进了旅游者信息手段的应用能力,使智能化革命有了广泛的用户基础。1.1课题背景旅游是人类社会发展到一定阶段后的一种社会活动。人们在满足休息、娱乐、文化等活动的需要后,离开定居地前往目的地,在那里停留一段时间。旅游业是在旅游活动的基础上发展起来的,以旅游者为服务对象和旅游者需求为中心的综合性产业,是资源密集型的新兴产业,综合服务和发展支持。旅游业主要包括旅行社业、旅游运输业、住宿餐饮业、风景名胜区业、购物业、娱乐业等重点产业,形成相对完整的产业链,为游客提供完善的服务。但现阶段我国旅游业还存在着信息化水平低、旅游产品开发水平低等问题。例如,大多数导游系统仍然停留在依靠旗帜和扬声器的人工阶段,绝大多数电子旅游系统集成度较低,只能提供音频等应用,但对于更丰富的服务,如图片、电子地图等地理信息,位置和其他服务不可用。另一方面,随着以谷歌Android系统和苹果IOS系统为代表的移动智能操作系统的应用和发展日益增多,智能终端广泛应用于移动终端、媒体播放器等领域。因此,在全球数字信息网络快速发展的背景下,通过地理定位与地图信息技术的结合,帮助游客更快地获取旅游景点的相关信息,基于移动设备的旅游相关应用已经成为实现智能旅游的重要载体因此,本文研究基于Android的旅游讲解助手APP软件的设计与实现具有重要的现实意义。1.2旅游系统的发展旅游信息化在发达国家经历了几十年的发展,涉及旅游目的地信息、旅游政府监管信息、旅游企业服务信息、旅游者个人信息和旅游产品信息五大类。随着理论和技术的不断进步,信息技术的应用也发生了几大变化。首先,上世纪50年代末,美国航空公司和IBM联合开发了世界上第一个计算机定位系统——SABRE,这是旅游信息化萌芽的标志;第二,上世纪70年代末,美国出台了《空中交通管制取消法》,增加了游客购票的选择,并将电脑订票系统推广到旅行社;第三,20世纪末,美国开始出现一种新的“电子机票”模式。随着信息技术的飞速发展,旅游系统也在飞速发展。谷歌2005年推出的谷歌地图就是一个典型的例子。中国旅游业的信息化始于上世纪80年代初。起步较晚,基础薄弱。总体水平较低。进入21世纪后,我国旅游信息化开始高速发展,包括旅行社、旅游饭店、景区等的信息化建设。各大旅游信息网站纷纷涌现。不仅网易、腾讯、新浪、搜狐等门户网站都有旅游板块,还有携程、去哪儿网等众多旅游电子商务网站。旅游系统最初是在PC机上实现的,但用户在旅游过程中需要随时了解最新信息、发布最新信息和使用定位功能。鉴于移动平台的普及,利用移动终端上的旅游系统资源更适合发展。1.3研究内容在分析旅游景点需求的同时,合理美观的界面设计,使用户体验效果良好。这个应用一般是旅游团用户使用的,用户可以提前查看相应旅游景点的介绍和游玩路线。用户在游览景区时,该应用可以实时向游客介绍景区的特色,以语音广播的形式播放,并推荐景区附近的其他景区和美食推荐。在本应用程序的设计中,采用MVP架构模式完成了整个代码的架构,完成了接口和数据存储的高效结合,使代码得到优化,应用程序使用顺畅,没有卡死等内存泄漏现象。主要功能及指标要求如下:(1)账号的注册和登录(2)旅游景点的浏览和简介(3)在游览景点时的语音播放景点介绍相关内容(4)在景点游览过程中可以推荐附近美食和景点(5)App界面要设计合理美观,用户体验效果好

2系统关键技术简介2.1Android系统简介Android是谷歌(Google)公司发布的基于Linux的开源手机平台,该平台由操作系统、中间件和应用软件组成,是第一个可以完全定制、免费、开放的手机平台。Android是一个完全免费的手机平台,使用Android并不需要授权费,而且因为Android平台有丰富的应用程序,也大幅度降低了应用程序的开发费用,可以节约15%~20%的手机制造成本。2.1.1Android特征Android底层使用开源的Linux操作系统,同时开放了应用程序开发工具,使所有程序开发人员都在统一、开放的开发平台上进行开发,保证了Android应用程序的可移植性。Android系统提供了访问硬件API库函数,用来简化像摄像头、GPS等硬件的访问过程。在内存和进程管理方面,Android具有自己的运行时和虚拟机。与Java和.NET运行时不同,Android运行时还可以管理进程的生命周期。Android为了保证高优先级进程运行和正在与用户交互进程的响应速度,允许停止或终止正在运行的低优先级进程,已释放被占用的系统资源。Android进程的优先级并不是固定的,而是根据进程是否在前台或是否与用户交互而不断变化的。在界面设计上,Android提供了丰富的界面控件供使用者调用,从而加快了用户界面的开发速度,也保证了Android平台上的程序界面的一致性。Android将界面设计与程序逻辑分离,使用XML文件对界面布局进行描述,有利于界面的修改和维护。Android提供轻量级的进程间通信机制Intent,使跨进程组件通信和发送系统级广播成为可能。通过设置组件的Intent过滤器,组件通过匹配和筛选机制,可以准确地获取到可以处理的Intent。Android提供了Service作为无用户界面、长时间后台运行的组件。Android是多任务系统,但受到屏幕尺寸的限制,同一时刻只允许一个应用程序在前台运行。Service无须用户干预,可以长时间、稳定地运行,可为应用程序提供特定的后台功能,还可以实现事件处理或数据更新等功能。Android支持高效、快速的数据储存方式,应用程序可以使用适合的方法保存和访问数据进程。同时,为了便于跨进程共享数据,Android提供了通用的共享数据接口ContentProvider,可以无须了解数据源、路径的情况下,对共享数据进行查询、添加、删除和更新等操作。2.1.2Android系统架构Android系统架构采用了分层的架构。Android系统分为四层,从高层到低层分别是应用程序层、应用程序框架层、系统运行层和Linux内核层。图2.1Android系统架构(1)应用程序层Android应用程序层包含了许多应用程序。例如,短信、联系人、电话、电子邮件、浏览器等。同时,开发人员也可以利用Java语言设计和编写属于自己的应用程序。相比其他手机操作系统,显得更加灵活和个性化。(2)应用程序框架层应用程序框架层是Android开发的基础,为应用程序层提供了各种所能用到的API,很多核心程序也是通过这些API来实现的。由于其内部的组件重用机制,开发人员可以直接使用其提供的的组件来快速地进行应用程序的开发,也可以通过继承来实现个性化的拓展。(3)系统运行库层系统运行库层包括系统库和AndroidRuntime。系统库是应用程序框架的支撑,是连接应用程序框架层与Linux内核层的重要纽带。程序在AndroidRuntime中执行,其运行时分为核心库和Dalvik虚拟机两部分。(4)Linux内核层Android操作系统是基于Linux内核,其核心系统服如安全性、内存管理、进程管理、网路协议以及驱动模型都依赖于Linux内核。LinuxKernel也作为硬件和软件之间的抽象层,它隐藏了具体硬件细节并为上层提供统一的服务。2.1.3Android应用组件Android开发四大组件分别是:活动(Activity),用于表现功能;服务(Service),用于后台运行服务,不提供界面呈现;广播接收器(BroadcastReceiver),用于接收广播;内容提供商(ContentProvider),支持在多个应用中存储和读取数据,相当于数据库。(1)Activity一个Activity通常展现为一个可视化的用户界面,它是Android程序与用户交互的窗口,也是Android组件中最基本也是最复杂的一个组件。从视觉效果来看,一个Activity占据当前的窗口,响应所有窗口时间,其具备控件,菜单等界面元素。从内部逻辑来看,Activity需要为了保持各个界面状态,做很多持久化的事情,还需要妥善管理生命周期和一些转跳逻辑。对于开发者而言,需要派生一个Activity的子类,进而进行编码实现各种功能方法。一般一个Android应用是由多个Activity组成的,Activity之间通过Intent进行通信。在Intent的描述结构中,有两个最重要的部分:动作和动作对应的数据。Android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity。(2)Service一个Service是一段长生命周期且没有用户界面的程序,只能后台运行,并且可以和其他组件进行交互,它可以用来开发如监控类程序。同Activity一样,Service也必须要在AndroidManifest.xml配置文件中注册。(3)BroadcastReceiver广播是一种被广泛运用在应用程序之间传输信息的机制,而BroadcastReceiver是对发送出来的广播进行过滤接收并响应的一类组件。广播接收器没有用户界面,但它们可以启动一个activity或service来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用多种方式来吸引用户的注意力——闪动背灯、震动、播放声音等。一般来说是在状态栏放一个持久的图标,用户可以打开它并获取消息。BroadcastReceiver既可以在AndroidManifest.xml中注册,也可以在运行时的代码中使用registerReceiver()进行注册。(4)ContentProvider内容提供者,作为应用程序之间唯一的共享数据途径,ContentProvider主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口。在Android中,对数据的保护是很严密的,除了放在SD卡中的数据,一个应用所持有的数据库、文件等内容,都不允许其他应用直接访问。但是可以通过ContentResolver类从该内容提供者中获取或存入数据。ContentProvider使用URI来唯一标识其数据集,这里的URI以content://作为前缀,表示该数据由ContentProvider来管理。ContentProvider使用时也必须要在AndroidManifest.xml配置文件中注册。2.2MVP模式与MVC模式MVP(Model-View-Presenter)模式,它是由MVC(Model-View-Controller)模式演变而来的。它们的基本思想有想通的地方:Model负责提供数据,View负责显示,Controller/Presenter的内部。而在MVC中,View可以直接从Model中读取数据。图2.2MVP与MVC对比图(1)MVP架构模式在Android开发中采用MVP架构,分别为模型层(Model)、视图层(View)和逻辑层(Presenter)。模型层用于提供数据源,负责对数据的存取操作,例如数据库的读写、网络数据的请求等;视图层负责UI处理,具体是一个View接口,由Activity或Fragment实现;逻辑层,用于实现业务逻辑,既可以调用UI逻辑,也可以处理网络请求逻辑,该层为纯Java类,不涉及任何AndroidAPI。(2)MVC架构模式MVC模式的三层架构,即视图层(View)、控制层(Controller)、模型层(Model)。视图层运行在浏览器上面用于展示Web应用程序的页面;控制层运行在服务器端,主要控制页面的切换和相关业务逻辑的调用;模型层主要封装了Web应用程序的业务逻辑,以及对数据库的访问。Controller负责处理流入的请求,其通过View来接受用户的输入,之后利用Model来处理用户的数据,最后把结果返回给View。3系统需求分析需求分析是软件开发的基础和前提,也是软件开发的关键因素之一。这个阶段是分析什么需要“实施”,而不是如何“实施”。需求分析的目的是开发人员对开发系统的“需求”或“需求”进行分析和梳理,确定系统需要实现哪些功能和任务。3.1总体需求分析要开发一个旅游讲解助手APP,首先需要做到旅游景点范围的明确,利于游客浏览热门景点的需求,确定大连市相应景点的添加;游客可以通过此APP了解大连市的热门景点,可通过语音播报来熟知某个景点;注册的用户需要填入准确的信息,注册之后才能登录到APP,才能查看景点的具体信息,也可以查看所在定位下的附近景点和附近美食;用户可以自主管理个人信息以及密码的修改。管理员注册和登录之后可以添加景点的具体信息。该软件通过Android移动终端和PC终端实现。移动终端主要供用户查看大连市相关景点,包括景点的具体信息以及到达景点后附近的景点和食物;有用户登录注册、修改昵称、修改密码、退出账号登录等功能。PC端是管理员添加大连风景名胜区的具体信息;它还包括管理员登录和注册。3.2功能性需求分析3.2.1旅游讲解助手APP端功能需求分析旅游讲解助手APP端是面向游客用户的,其目的是让游客通过此APP来了解到大连市景点的具体信息,为旅游出行做好攻略等准备。旅游讲解助手APP端的功能需求的具体内容如下:用户登录:用户通过昵称(账号)和密码的验证后可进入APP。用户注册:用户若未注册,则通过昵称(账号)、邮箱、密码进行账号的注册。景点列表浏览:可浏览大连市热门景点。景点详情信息:可知道大连市某个景点的具体信息、简介等。景点导航:根据景点的坐标通过百度API的请求中传入城市名称、目的地等数据参数来查询旅游地、景点等信息,进行距离查询或导航到达。景点信息语音播报:景点的相关信息可通过语音播报的形式表现。附近景点:在游玩过程中可知道身处景点的附近景点。附近美食:在游玩过程中可知道身处景点的附近美食。用户上传头像:用户在登陆后可以上传自己的头像。用户修改昵称:用户在登陆后可以修改用户昵称。用户修改密码:用户在登陆后可以修改用户昵称。用户退出登录账号:用户在退出登录账号后会自动退出APP。旅游讲解助手APP端的功能需求用例图如下图所示:图3.1APP端的功能需求用例图3.2.2旅游讲解助手PC端的功能需求分析旅游讲解助手PC端是管理员进行添加景点等功能,其目的是通过管理员来添加大连市热门的景点及其相关信息。旅游讲解助手PC端的功能需求的具体内容如下:管理员登录:管理员通过邮箱、密码验证后进入景点添加界面。管理员注册:通过账号、邮箱、密码等完成管路员账号的注册。景点添加:添加景点的名称、坐标、详情介绍、景点图片。3.3系统环境需求(1)开发环境:硬件环境:台式计算机;Windows10。软件环境:IntelliJIDEA2021.1x64;AndroidStudio;JDK;MySQL。(2)运行环境:硬件环境:Android手机;台式计算机;Windows10。软件环境:Android操作系统;GoogleChrome浏览器。

4系统概要设计系统概要设计是开发者基于用户交互过程和用户需求形成交互框架和可视框架的过程,其结果通常是交互控制配置、以反映接口元件分组和接口整体板式的页帧图的形式呈现。

概要设计的主要任务是将需求分析得到的系统扩展用例图转换成软件结构和数据结构。4.1系统结构设计旅游讲解助手APP软件是以AndroidStudio为开发平台实现的移动应用软件,实现过程中利用百度API提供的WebService获取地图信息,通过百度API的请求中传入城市名称、目的地等数据参数来查询旅游地、景点等信息,利用SAXParser对获取到的XML数据文件进行解析,并将解析结果在UI界面中展示。图4.1系统功能结构设计图4.2前端功能模块的设计前端功能模块的设计分为Android用户端和PC端。Android用户终端大致分为用户账号注册和注册模块、景点查询模块、景点相关信息模块、景点介绍语音广播模块、景点导航模块。通过与服务器的数据交互来实现该APP的使用。用户登录APP后,可以查询大连市的观光景点介绍和观光路线等观光景点信息。用户在游览某个景点时使用这个应用程序,为游客实时介绍景点的特色,并通过声音广播进行播放。可以看到观光景点附近其他的观光景点和美食介绍等目的。界面设计既合理又美丽又方便。PC端的实现主要是在于开发一个Web工程,配置数据库服务器和Web服务器,并在web工程中纳入两个服务器的驱动,以此通过Web工程实现用户端HTTP请求的响应,并将最终结构反馈给用户端。4.3后端功能模块的设计后端的服务器端主要实现PC端、数据库和Android手持端的连接。第一是关于数据的存储功能,这里主要体现在管理员账号注册、登录的信息储存,用户账号注册、登录的信息存储,景点相关信息的存储。第二个功能是和手机端实现数据交互。在数据交互的过程中,用户可以实现从服务器查询景点位置信息、景点信息语音播报等功能。操作端对数据库的访问和数据存储。4.4数据库设计本系统的数据库使用的是MySQL,通过JDBC驱动连接数据库。实际上,本系统的数据库十分简单,只有三个数据表,三者之间并没有直接的关系,所以在这里就省略了数据库的E-R图。下面是三个数据表的结构设计:管理员数据表该表是用来记录管理员的姓名、密码以及邮箱。表4.1管理员数据表字段名字段类型 宽度 索引标题idINT10主索引管理员编号user_nameVARCHAR30管理员姓名passwordVARCHAR255管理员密码emailVARCHAR255管理员邮箱用户数据表该表是用来记录用户的昵称、密码、邮箱以及头像。表4.2用户数据表字段名字段类型 宽度 索引标题idINT10主索引用户编号user_nameVARCHAR30用户昵称passwordVARCHAR255用户密码emailVARCHAR255用户邮箱avatarVARCHAR255用户上传头像景点信息数据表该表是用来记录景点的名称、详情、经度、纬度以及景点图片。表4.3景点信息数据表字段名字段类型 宽度 索引标题idINT11主索引景点编号nameVARCHAR20景点名称infoVARCHAR500景点详情longitudeVARCHAR20景点经度latitudeVARCHAR20景点纬度imageVARCHAR500景点图片

5系统详情设计与实现在本文上一章中概要地介绍了系统的结构设计和数据设计,本章则介绍旅游讲解助手APP的详情设计和实现情况。系统详情阶段将为每个模块完成的功能进行具体的描述,把功能描述变为精确的过程描述。因为Android系统的开发特点,本章将首先进行系统界面的介绍,即界面层的设计,进而介绍控制层和数据访问层的设计。5.1登录与注册界面设计登录与注册界面主要分为两个模块,分别是用户模块和管理员模块。5.1.1用户模块用户模块是Android手机端的功能模块,其中包括了用户的登录界面和用户的注册界面。点击此APP会直接显示欢迎页面,如图5.1所示。图5.1欢迎页面欢迎页面经过延时效果直接跳转到登录页面,如图5.2所示。登录页面输入邮箱和密码,经验证与数据库内储存一致则进入APP首页。图5.2登录页面如若用户没有注册,则新用户可以点击注册按钮跳转到注册页面,如图5.3所示。目前注册界面需要填写用户名、邮箱、密码,如若未填写则会有相应提示,邮箱通过正则表达式来验证邮箱格式,密码也通过正则表达式来检验强弱,注册成功后会给予提示注册成功跳转回登录页面。图5.3注册页面主要实现代码:欢迎页面

publicclassWellComeActivityextendsAppCompatActivity{

Handlerhandler=newHandler()

{

@Override

publicvoidhandleMessage(@NonNullMessagemsg){

super.handleMessage(msg);

if(SharePrenUtils.getInstance(WellComeActivity.this).isLogin())

{

startActivity(newIntent(WellComeActivity.this,MainActivity.class));

}

else

{

startActivity(newIntent(WellComeActivity.this,LoginActivity.class));

}

finish();

}

}

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_well_come);

//2秒之后跳转的登录页面

handler.sendEmptyMessageDelayed(0,2000);

}

}登录页面publicclassLoginActivityextendsBaseActivity{

ActivityLoginBindingbinding;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

binding=ActivityLoginBinding.inflate(getLayoutInflater());

setContentView(binding.getRoot());

binding.login.setOnClickListener(view->{

login();

});

binding.regis.setOnClickListener(view->{

startActivity(newIntent(this,RegisActivity.class));

});

}

privatevoidlogin(){

Stringname=.getText().toString();

if(TextUtils.isEmpty(name))

{

Toast.makeText(this,"用户名不能为空",Toast.LENGTH_SHORT).show();

return;

}

Stringpass=binding.pass.getText().toString();

if(TextUtils.isEmpty(pass))

{

Toast.makeText(this,"密码不能为空",Toast.LENGTH_SHORT).show();

return;

}

Stringurl=Contstans.host+"/user/login";

RequestParamsparams=newRequestParams(url);

params.setAsJsonContent(true);

LoginBeanbean=newLoginBean();

bean.setUsername(name);

bean.setPassword(pass);

params.setBodyContent(newGson().toJson(bean));

showDialog();

x.http().post(params,newCallback.CommonCallback<LoginResultBean>(){

@Override

publicvoidonSuccess(LoginResultBeanresult){

//返回为0代表登录成功

if(result!=null)

{

showtoast("登录成功");

//保存用户名

SharePrenUtils.getInstance(LoginActivity.this)

.putUserInfo(result);

startActivity(newIntent(LoginActivity.this,MainActivity.class));

finish();

}else{

showtoast("用户名或者密码错误");}

}

@Override

publicvoidonFinished(){

hideDialog();}});}

}注册页面publicclassRegisActivityextendsBaseActivity{

ActivityRegisBindingbinding;

privateintGRADE_SCORE;

@Override

protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);

binding=ActivityRegisBinding.inflate(getLayoutInflater());

setContentView(binding.getRoot());

binding.pass.addTextChangedListener(newTextWatcher(){

@Override

publicvoidafterTextChanged(Editableeditable){

Stringtext=binding.pass.getText().toString();

if(TextUtils.isEmpty(text))

return;

//判断密码的强度

PasswordStrengthstr=PasswordStrength.calculateStrength(text);

binding.tvQiangdu.setText("密码强度:"+str.getText(RegisActivity.this));

gressBar.getProgressDrawable().setColorFilter(str.getColor(),android.graphics.PorterDuff.Mode.SRC_IN);

if(str.getText(RegisActivity.this).equals("低")){

gressBar.setProgress(33);

}elseif(str.getText(RegisActivity.this).equals("中")){

gressBar.setProgress(66);

}elseif(str.getText(RegisActivity.this).equals("高")){

gressBar.setProgress(100);

}else{

gressBar.setProgress(0);}

}});binding.regis.setOnClickListener(view->{

regis();

});}/**注册按钮*/privatevoidregis(){

Stringname=.getText().toString();

if(TextUtils.isEmpty(name))

{Toast.makeText(this,"用户名不能为空",Toast.LENGTH_SHORT).show();

return;}

Stringpass=binding.pass.getText().toString();

if(TextUtils.isEmpty(pass))

{Toast.makeText(this,"密码不能为空",Toast.LENGTH_SHORT).show();

return;}

Stringyouxiang=binding.youxaing.getText().toString();

if(TextUtils.isEmpty(youxiang))

{Toast.makeText(this,"邮箱不能为空",Toast.LENGTH_SHORT).show();

return;}

if(!isEmail(youxiang))

{Toast.makeText(this,"不是有效邮箱",Toast.LENGTH_SHORT).show();

return;}Stringurl=Contstans.host+"/user/regist";

RequestParamsparams=newRequestParams(url);

params.addBodyParameter("username",name);

params.addBodyParameter("email",youxiang);

params.addBodyParameter("password",pass);

showDialog();

x.http().post(params,newCallback.CommonCallback<String>(){@Override

publicvoidonSuccess(Stringresult){

if(result.equals("1"))

{

//保存用户名

SharedPreferencessharedPreferences=getSharedPreferences(Contstans.use_info,MODE_PRIVATE);

sharedPreferences.edit().putString("name",name).commit();

sharedPreferences.edit().putString("email",name).commit();

Toast.makeText(RegisActivity.this,"注册成功",Toast.LENGTH_SHORT).show();

finish();}else{showtoast("注册失败");}

}@Override

publicvoidonFinished(){hideDialog();}

});}/**判断密码强度@returnZ=字母S=数字T=特殊字符*/

privateStringpasswordStrong(StringpasswordStr){

if(TextUtils.equals("",passwordStr)){

return"出现故障";}

StringregexZ="\\d*";

StringregexS="[a-zA-Z]+";

StringregexT="\\W+$";

StringregexZT="\\D*";

StringregexST="[\\d\\W]*";

StringregexZS="\\w*";

StringregexZST="[\\w\\W]*";

if(passwordStr.matches(regexZ)){

GRADE_SCORE=20;

return"弱";}

if(passwordStr.matches(regexS)){

GRADE_SCORE=20;

return"弱";}

if(passwordStr.matches(regexT)){

GRADE_SCORE=20;

return"弱";}

if(passwordStr.matches(regexZT)){

GRADE_SCORE=60;

return"中";}

if(passwordStr.matches(regexST)){

GRADE_SCORE=60;

return"中";}

if(passwordStr.matches(regexZS)){

GRADE_SCORE=60;

return"中";}

if(passwordStr.matches(regexZST)){

GRADE_SCORE=90;

return"强";}

returnpasswordStr;}

/**设置progressBar值*@paramscore*/

privatevoidsetProgressBarColour(intscore){intcolor=0;

if(score<30){

color=getResources().getColor(android.R.color.holo_red_light);

}elseif(score<70){

color=getResources().getColor(android.R.color.holo_orange_light);

}else{

color=getResources().getColor(android.R.color.holo_green_light);

}

ClipDrawabled=newClipDrawable(newColorDrawable(color),Gravity.

LEFT,ClipDrawable.HORIZONTAL);

gressBar.setProgressDrawable(d);

gressBar.setProgress(score);

}

//判断是否是邮箱

publicbooleanisEmail(Stringemail){

Stringstr="^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)"

+"|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";

Patternp=Ppile(str);

Matcherm=p.matcher(email);

returnm.matches();

}

}5.1.2管理员模块管理员模块是通过该系统PC端来实现的,其包括了管理员登录和管理员注册两个页面,如下图所示。管理员通过验证登录后可进入景点添加页面。图5.4管理员登录页面图5.5管理员注册页面5.2景点信息模块设计首页页面是由三个fragment架构的,其分为景点、附近、我的三个fragment。景点页面的景点是由后台添加的,由PC端的页面进入景点管理页面。管理者通过登录进入景点添加页面,景点的相关数据也是通过接口传入后台并将相应的数据存入数据库,APP的景点页面即显示相应的景点。(1)景点页面景点页面的fragment用的是RecyclerView控件,通过自定义的适配器HomeAdapter来展示景点的相关内容,其包括景点名称、景点详情、景点图片、景点的经纬度。图5.6景点页面主要实现代码:publicclassHomeFragmentextendsFragment{publicViewonCreateView(@NonNullLayoutInflaterinflater,

ViewGroupcontainer,BundlesavedInstanceState){

Viewroot=inflater.inflate(R.layout.fragment_home,container,false);

initViews(root);

initData();

returnroot;

}

privatevoidinitData(){

//后台接口获取景区列表

Stringurl=Contstans.host+"/scenic";

RequestParamsparams=newRequestParams(url);

x.http().get(params,newCallback.CommonCallback<List<PlaceBean>>(){

@Override

publicvoidonSuccess(List<PlaceBean>result){

if(result!=null){homeAdapter.setList(result);}else{//没有数据}}});}

/**初始化布局*/

HomeAdapterhomeAdapter;

privateRecyclerViewrecyclerView;

privatevoidinitViews(Viewview){

recyclerView=view.findViewById(R.id.list);

recyclerView.setLayoutManager(newLinearLayoutManager(getContext()));

homeAdapter=newHomeAdapter(getContext());

recyclerView.setAdapter(homeAdapter);

homeAdapter.setListenr(bean->{

DeatilsActivity.start(getContext(),bean);

});}}publicclassHomeAdapterextendsRecyclerView.Adapter{

publicvoidsetListenr(OnClickListenrlistenr){

this.listenr=listenr;}

publicvoidsetLatLng(LatLnglatLng){

this.latLng=latLng;}

publicHomeAdapter(Contextcontext){

this.context=context;}

publicvoidsetList(List<PlaceBean>list){

if(list!=null){

this.list=list;

notifyDataSetChanged();

}

}

@NonNull

@Override

publicRecyclerView.ViewHolderonCreateViewHolder(@NonNullViewGroupparent,intviewType){

Viewview

=LayoutInflater.from(context)

.inflate(R.layout.item_home,parent,false);

returnnewHomeViewHolder(view);}

@Override

publicvoidonBindViewHolder(@NonNullRecyclerView.ViewHolderholder,intposition){

PlaceBeanplaceBean=list.get(position);

HomeViewHolderviewHolder=(HomeViewHolder)holder;

if(placeBean.getImages()!=null)

{Stringurl=null;

if(placeBean.getImages().contains(",")){

String[]urls=placeBean.getImages().split(",");

url=Contstans.host+urls[0].replaceAll("\\\\","/");

}else{

url=Contstans.host+placeBean.getImages().replaceAll("\\\\","/");

Glide.with(context)

.load(url)

.error(R.mipmap.ico_error_img)

.into(viewHolder.imageView);}

viewHolder.textView.setText(placeBean.getName());

viewHolder.textView1.setText(placeBean.getInfo());

viewHolder.itemView.setOnClickListener(view->{

if(listenr!=null){

listenr.onClick(placeBean);}});

//跳转到百度地图导航

viewHolder.textView2.setOnClickListener(view->{

//后台填的是反的,所以这里也反一下

Stringlog=placeBean.getLatitude();

Stringlat=placeBean.getLongitude();

if(TextUtils.isEmpty(lat)||TextUtils.isEmpty(log))

return;

Utils.naVgationToBaiduMap(context,newLatLng(Double.parseDouble(lat),Double.parseDouble(log)));

});}

@Override

publicintgetItemCount(){

if(list==null)

return0;

else

returnlist.size();}classHomeViewHolderextendsRecyclerView.ViewHolder{

ImageViewimageView;

TextViewtextView;

TextViewtextView1;

TextViewtextView2;

publicHomeViewHolder(@NonNullViewitemView){

super(itemView);

imageView=itemView.findViewById(R.id.image);

textView=itemView.findViewById(R.id.title);

textView1=itemView.findViewById(R.id.content);

textView2=itemView.findViewById(R.id.distans);}}

publicinterfaceOnClickListenr{

voidonClick(PlaceBeanbean);}}/**跳转百度导航*@paramcontext*@paramlatLng*/

publicstaticvoidnaVgationToBaiduMap(Contextcontext,LatLnglatLng){Intentintent=context.getPackageManager().getLaunchIntentForPackage("com.baidu.BaiduMap");

if(intent==null){

Toast.makeText(context,"手机未安装百度地图",Toast.LENGTH_SHORT).show();

return;}

IntentbdNav=newIntent();

//步行导航

bdNav.setData(Uri.parse("baidumap://map/walknavi?origin="+latLng.latitude+","+latLng.longitude+"&destination=43.81710,125.38332&coord_type=bd09ll&src=andr.baidu.openAPIdemo"));

//骑行导航

//bdNav.setData(Uri.parse("baidumap://map/bikenavi?origin="+bdGPS[0]+","+bdGPS[1]+"&destination=43.81710,125.38332&coord_type=bd09ll&src=andr.baidu.openAPIdemo"));//驾车导航//bdNav.setData(Uri.parse("baidumap://map/navi?query=解放大路与人民大街交汇&src=andr.baidu.openAPIdemo"));

context.startActivity(bdNav);

}(2)景点详情页面景点详情页面显示景点名称、详情介绍。其介绍可由语音进行播报,这里引用了讯飞开放平台的在线语音合成。语音合成,又称文语转换(TexttoSpeech,TTS)技术,解决的主要问题是如何将文字信息转化为可听的声音信息(即音频数据)。图5.7景点详情页面主要实现代码:publicclassDeatilsActivityextendsAppCompatActivity{

privateStringTAG="DeatilsActivity";

publicstaticvoidstart(Contextcontext,PlaceBeanbean){

Intentstarter=newIntent(context,DeatilsActivity.class);

starter.putExtra("bean",bean);

context.startActivity(starter);}

ActivityDeatilsBindingbinding;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

binding=ActivityDeatilsBinding.inflate(getLayoutInflater());

setContentView(binding.getRoot());

mediaPlayer=newMediaPlayer();

initTst();

initData();}

//初始化讯飞的合成语音

//语音合成对象

//默认发音人

privateStringvoicer="xiaoyan";

privateSpeechSynthesizermTts;

/**初始化监听。*/

privateInitListenermTtsInitListener=newInitListener(){

@Override

publicvoidonInit(intcode){

Log.d(TAG,"InitListenerinit()code="+code);

if(code!=ErrorCode.SUCCESS){

showTip("初始化失败,错误码:"+code+",请点击网址/document/error-code查询解决方案");}else{//初始化成功,之后可以调用startSpeaking方法//注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,//正确的做法是将onCreate中的startSpeaking调用移至这里}}};

privatevoidshowTip(finalStringstr){

Toast.makeText(this,str,Toast.LENGTH_SHORT).show();}

privatevoidinitTst(){//讯飞初始化

mTts=SpeechSynthesizer.createSynthesizer(this,mTtsInitListener);

binding.btYuyin.setOnClickListener(view->{

if(null==mTts){

//创建单例失败,与21001错误为同样原因,参考/forum.php?mod=viewthread&tid=9688

this.showTip("创建对象失败,请确认libmsc.so放置正确,且有调用createUtility进行初始化");

return;

}

Stringtext=binding.tvContent.getText().toString();

if(TextUtils.isEmpty(text))

return;

mTts.startSpeaking(text,newSynthesizerListener(){});

});}

@Override

protectedvoidonDestroy(){

super.onDestroy();

//释放资源

if(mediaPlayer!=null){

mediaPlayer.stop();

mediaPlayer.release();

mediaPlayer=null;

}if(mTts!=null){

mTts.stopSpeaking();

mTts.destroy();}}MediaPlayermediaPlayer;

privatevoidinitData(){

PlaceBeanplaceBean=(PlaceBean)getIntent().getSerializableExtra("bean");

if(placeBean!=null)

{if(placeBean.getImages()!=null)

{Stringurl=null;

if(placeBean.getImages().contains(",")){

String[]urls=placeBean.getImages().split(",");

url=Contstans.host+urls[0].replaceAll("\\\\","/");

}else

url=Contstans.host+placeBean.getImages().replaceAll("\\\\","/");

Glide.with(this)

.load(url)

.error(R.mipmap.ico_error_img)

.into(binding.imgImg);}

binding.title.setText("景点名称:"+placeBean.getName());

binding.tvContent.setText("文字介绍:"+placeBean.getInfo());}}privatevoidinitMediaPlayer(Stringurl){

try{

mediaPlayer.setDataSource(url);

mediaPlayer.prepare();

}catch(IOExceptione){

e.printStackTrace();

}

}

}5.3附近景点与附近美食模块设计附近模块直接引用了百度地图开放平台,用到的是地图和定位的sdk。由附近景点和附近美食两部分组成,地图可以放大或缩小。图5.8附近页面主要实现代码:publicclassDashboardFragmentextendsFragment{

publicViewonCreateView(@NonNullLayoutInflaterinflater,

ViewGroupcontainer,BundlesavedInstanceState){

Viewroot=inflater.inflate(R.layout.fragment_dashboard,container,false);

initviews(root);

initData();

returnroot;}

privateinttype=0;//0是附近的景点1是附近的美食

privatevoidinitviews(Viewroot){

textureMapView=root.findViewById(R.id.map);

button=root.findViewById(R.id.location);

buttonMeiShi=root.findViewById(R.id.location_meishi);

baiduMap=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论