2018android项目驱动式开发教程源码与第十一章_第1页
2018android项目驱动式开发教程源码与第十一章_第2页
2018android项目驱动式开发教程源码与第十一章_第3页
2018android项目驱动式开发教程源码与第十一章_第4页
2018android项目驱动式开发教程源码与第十一章_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

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

文档简介

第11章综合实例:健身助手的实现11.1系统功能介绍和架构设计本章将主要介绍通过Android终端和云平台进行功能整合,从而实现基于云服务的移动APP,在该应用中,云端采用百度云为基础,而客户端在采用Android4.1.2。11.1.1系统功能介绍本项目的服务端采用百度云服务,该服务是由接入层、计算曾和数据层三方面构成,如图所示。Android客户端只负责与服务器接入层之间的数据交互,通过Apache的HttpClient向服务器提交HTTP请求,从而获取服务器的数据响应来实现AndroidAPP和云服务之间的通讯。11.1.1系统功能介绍本系统主要实现有以下三方面的功能:用户可以通过GPS、基站和WIFI定位当前用户的位置,并显示地图中。当用户需要查询当地公交时,可以通过本系统获取公交线路的途径站点。用户可以通过本系统进行多种语言的翻译,帮助异地解决语言问题11.1.1系统功能介绍图11-1百度云服务的架构图11.1.2系统架构设计

本系统采用目前最为普遍的MVC架构,即分为视图层、控制层和业务逻辑层,用户不直接和云服务的数据库进行交互,而是与服务端的接入层进行数据交换,再由计算层与数据层进行交换,从而把数据返回给用户。视图层:用于在地图中显示用户的各种请求,结果控制层返回的数据。控制层:主要负责视图层和业务逻辑层之间的交互,调用业务逻辑层,并把业务数据进过处理发送给视图层进行展示。11.1.2系统架构设计

业务逻辑层:负责实现系统中的业务逻辑部分,主要对云服务访问的封装和各功能之间的业务关系的处理。此外本系统中采用Apache提供的开源软件HttpClient向服务器提交用户请求,通过该软件可以模拟HTTP请求,从而获取服务器的响应数据,这些数据应采用轻量级网络数据交换格式——JSON数据格式,使开发者方便的进行数据解析和展示。11.2百度APIKey的申请读者在使用百度定位SDK之前首先需要获取百度定位的APIKey,该Key与百度账户相关联,因此读者必须先有一个百度账号,才能获取APIKEY。在注册并登录百度账号后,进入百度地图API的AndroidSDK页面,在该页面左侧有一个“获取密钥”的导航栏,单击进入则显示出APIKey申请页面,在其中填入与应用相关的信息,最后单击“生成API密钥”就会获得一个APIKey,当申请完APIKey之后可以单击左侧导航栏中的“我的Key”来查看已申请的Key,如图所示。11.2百度APIKey的申请11.3JSON数据的解析在本系统中Android端与云服务之间的交互采用JSON作为数据交换格式。JSON是一种轻量级的数据交换格式,该格式既能被人所方便的读取,也可以被计算机进行解析和生成,同时JSON也是一种与语言无关的数据交换格式,结构非常类似XML。11.3JSON数据的解析通过JSON数据具有相互嵌套的特点,其主要的数据类型有以下两种:对象(JSONObject):该结构由键值对数据组成,如格式{KEY:VALUE,KEY:VALUE,...}。在面向对象的语言中,KEY为该对象的属性,VALUE为对象所对应的属性值,类似于JAVA中的MAP类型。当系统需要数据时,只需要通过提前约定的KEY找到对应的值即可获取数据,每个对象值的类型可以是数字、字符串、数组、JSON对象/数组几种。。11.3JSON数据的解析数组(JSONArray):该结构由中括号“[]”括起来,而其中的每一项则使用大括号“{}”括起来,如结构[{KEY:VALUE,KEY:VALUE,KEY:VALUE},{KEY:VALUE,KEY:VALUE,KEY:VALUE}],当需要取值时和所有语言一样,听过索引获取,每个元素的类型可以是数字、字符串、数组、JSON对象/数组几种。11.3JSON数据的解析完成JSON数据的对象和数组的解析使用最多的就是JSONArray和JSONObject两个类,主要功能如下:JSONArray:

表示一个JSON数组,它可以完成Java集合与JSON字符串之间的相互转换。JSONObject:

表示一个JSON对象,它可以完成Java对象和JSON字符串之间的相互转化。11.4公交线路查询的实现百度地图实现实时公交查询的功能。目前百度地图上的许多功能都是基于百度LBS来实现的,公交查询页也不例外。用户通过统一的LBS查询结果来获取所有POI(兴趣点)数据,然后再通过统一ID进行路径查询,并显示在地图中,如图所示。具体代码分为两部分完成,第一部分为在百度LBS中查询相关城市公交信息,并从所有获得的POI中检出类型为公交线路的信息,然后得到该POI信息的ID号,通过该ID号就可以查询出对应的公交线路,具体代码如下:11.4公交线路查询的实现1publicvoidsearchButtonProcess(Viewv){2busLineIDList.clear();3busLineIndex=0;4mBtnPre.setVisibility(View.INVISIBLE);5mBtnNext.setVisibility(View.INVISIBLE);6EditTexteditCity=(EditText)findViewById(R.id.city);7EditTexteditSearchKey=(EditText)findViewById(R.id.searchkey);8//发起poi检索9mSearch.searchInCity((newPoiCitySearchOption()).city(10editCity.getText().toString())11.keyword(editSearchKey.getText().toString()));12}11.4公交线路查询的实现第2行代码用于清除busLineIDList值。第3行代码初始化busLineIndex的值。第6~7行代码用于初始化EditText控件。第9~11行代码通过获取输入框内的是通过PoiCitySearchOption发起公交检索。

11.5百度实时翻译的实现百度翻译接入服务是百度面向开发者推出的免费翻译服务开放接口,允许任何第三方应用或网站通过接入该服务实现多语言的实时翻译。作为应用开发者,只需要通过调用所提供的API,并传入待翻译的内容,同时指定要翻译的源语言和目标语言种类,就可以得到相应的翻译结果。目前,百度翻译服务提供多个语种互译服务,覆盖英语、日语、韩语、西班牙语、法语、泰语、阿拉伯语、俄语等热门语种。11.5百度实时翻译的实现该服务主要包括5个功能:支持简单的标准RESTAPI。支持多种语言间互译:中英、英中、中日、日中、中韩、韩中、中法、法中等语言方面的翻译服务。支持显式指定翻译的源语言和目标语言语种。支持自动判断源语言语种,并根据一定规则设置目标语言语种。默认翻译API使用频率为每个IP1000次/小时,支持扩容。11.5百度实时翻译的实现百度翻译服务通过HTTP的POST或者GET操作来获取原文的翻译,具体有两方面的数据交换格式,一个是服务器提交格式,另一个则是服务器返回数据格式,具体说明如下:服务器提交格式11.5百度实时翻译的实现11.5百度实时翻译的实现签名生成方法如下:1、将请求参数中的APPID(appid),翻译query(q,注意为UTF-8编码),随机数(salt),以及平台分配的密钥(可在管理控制台查看)按照appid+q+salt+密钥的顺序拼接得到字符串1。2、对字符串1做md5,得到32位小写的sign。

11.5百度实时翻译的实现注意:1、请先将需要翻译的文本转换为UTF-8编码2、在发送HTTP请求之前需要对各字段做URLencode。3、在生成签名拼接appid+q+salt+密钥字符串时,q不需要做URLencode,在生成签名之后,发送HTTP请求之前才需要对要发送的待翻译文本字段q做URLencode。2)服务器返回数据格式:服务器返回数据格式见表11.5百度实时翻译的实现11.5百度实时翻译的实现以上便是百度翻译服务的使用方法,那么对于Android程序来说,主要完成两方面的工作:一个是向服务器的提交翻译请求;另一个则是从服务器上获取翻译结果,并显示在屏幕中。11.5百度实时翻译的实现在本模块最重要的就是网络交互的线程代码,具体代码如下:1public

void

run(){2 //TODOAuto-generatedmethodstub3 //HTTPGET操作对象4 HttpGethttpGet=newHttpGet(getTranslateURL(mSrcText,mTranslateIndex));5 HttpClienthttpClient=newDefaultHttpClient();6 try{7 HttpResponsehttpResponse=httpClient.execute(httpGet);8 if(httpResponse.getStatusLine().getStatusCode()9 ==HttpStatus.SC_OK){10 StringtranslateData=EntityUtils.toString(httpResponse11.5百度实时翻译的实现11 .getEntity());12 //把数据放到消息中发送给主线程13 Messagemsg=newMessage();14 Bundledata=newBundle();15 data.putString("TRAN_DATA",translateData);16 msg.setData(data);17 mTranslateHandler.sendMessage(msg);18 }19 }catch(ClientProtocolExceptione){20 //TODOAuto-generatedcatchblock21 e.printStackTrace();22 }catch(IOExceptione){11.5百度实时翻译的实现23 //TODOAuto-generatedcatchblock24 e.printStackTrace();25 }26}第2~3行代码用于产生随意数,在接下来进行md5加密。第4行代码中的getTranslateURL()函数是一个自定义函数,用于获取完整GET操作地址,并通过这个地址初始化HttpClient工具中的HttpGet对象,该对象负责执行与云服务之间的GET操作。第5行代码用于创建一个HttpClient对象,该对象通过执行HttpGet对象最终实现与云服务的交互。第8行和第9行代码用于判断云服务返回的状态码,当返回结果为200时,表示云服务响应正确。第10行代码表示从服务器返回的数据中提取所需内容,然后发送给主线程进行下一步处理。11.5百度实时翻译的实现当线程把数据返回后接下来就是解析这些数据和展示数据,数据解析的代码如下:1privateStringparseTranslateData(StringtranslateData){2 //TODOAuto-generatedmethodstub3 StringresData="";4 try{5 JSONObjecttranslateRes=newJSONObject(translateData);6 JSONArraytranslateArray=translateRes.getJSONArray("trans_result");7 for(inti=0;i<translateArray.length();i++){8 resData+=(translateArray.getJSONObject(i).9 getString("dst")+"\n");11.5百度实时翻译的实现10 }11 }catch(JSONExceptione){12 //TODOAuto-generatedcatchblock13 e.printStackTrace();14 }15 returnresData;16}第5行可以把云服务返回的数据转化为JSON对象。第6行可以从解析后的JSON对象中提取翻译的结果,并组成一个JSON数组。第7~10行从JSON数组中提取每个元素中的结果。11.6健身实时计数的实现11.6.1手电筒功能的实现

手电筒功能主要是调用Camera的控制来实现手电筒的开启与关闭,在使用闪关灯之前,注意使用Camera.open()方法打开摄像头,获取Camera对象。然后通过camera对象getParamerers()方法获取到Parameters参数。关闭闪光灯的时候,也是通过Parameters参数进行设置的。其功能的实现主要分为两个步骤:实现打开和关闭闪光灯,而实现操作闪光灯主要通过Camera类。自定义闪光灯的按钮,用于控制闪光灯的开启关闭。11.6健身实时计数的实现具体代码,如下所示:1publicvoidonClick(Viewv){2ToggleButtontb=(ToggleButton)v;3Camera.Parametersparam=camera.getParameters();4if(!tb.isChecked()){5param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);6bj.setBackgroundResource(R.drawable.bjon);7}else{8param.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);9bj.setBackgroundResource(R.drawable.bjoff);10}11camera.setParameters(param);12}11.6健身实时计数的实现第3行代码使用getParamerers()方法获取到Parameters参数。第4行代码用于判断手电筒的开启状态。第5行代码用于配置闪光灯开启。第6行代码用于改变显示状态。第11行代码用于设置闪光灯状态。11.6健身实时计数的实现11.6.2俯卧撑与引体向上信息采集的实现俯卧撑和引体向上主要引用接近与加速度传感器技术,原理就是通过手机端的各种传感器进行采集环境(手机传感器随着运动所产生参数的变化)的变化值,从而实现俯卧撑与引体向上信息采集的功能。具体代码如下:1 publicvoidonSensorChanged(SensorEventevent){2//TODOAuto-generatedmethodstub3float[]values=event.values;4intsensorType=event.sensor.getType();5StringBuildersb=null;6finalfloatalpha=(float)0.8;7gravity[0]=alpha*gravity[0]+(1-alpha)*event.values[0];11.6健身实时计数的实现8gravity[1]=alpha*gravity[1]+(1-alpha)*event.values[1];9gravity[2]=alpha*gravity[2]+(1-alpha)*event.values[2];10linear_acceleration[0]=event.values[0]-gravity[0];11linear_acceleration[1]=event.values[1]-gravity[1];12linear_acceleration[2]=event.values[2]-gravity[2];13 System.out.println("x"+linear_acceleration[0]+"y"+linear_acceleration[1]+"z"+linear_acceleration[2]);14longcurrentTime=SystemClock.elapsedRealtime();15longspaceTime=currentTime-lastTime;16lastTime=currentTime;17if(linear_acceleration[0]>1||linear_acceleration[2]>1)18if(spaceTime>35){19if(count!=-1){11.6健身实时计数的实现20mp=MediaPlayer.create(this,R.raw.refreshing_sound);21mp.start();22}23++count;24Stringtotalstr=preferences.getString("total",null);25totalTV.setText(String.valueOf(1+(int)Integer26.parseInt(totalstr)));27editor.putString("total",totalTV.getText().toString());28mit();29countTV.setText(String.valueOf(count));30}31}11.6健身实时计数的实现第4行代码用于获取传感器的类型。第7~9行代码主要使用低通滤波器分离重力加速度第10~12行代码主要使用高通滤波器剔除重力干扰第14行代码通过SystemClock.elapsedRealtime()获取系统时钟。第18行代码用于判断两次变化间隔时间大于一定值,去除外界因素的影响。第20、21行代码用于提示一个引体向上记录完成第23行代码用于对引体向上数据更新。第24~28行代码用于提交记录的数据。第29行代码用于更新界面显示。11.6健身实时计数的实现俯卧撑信息采集的工作:首先俯卧撑利用了接近传感器,我们根据人体到手机屏幕的距离的大小进行判断与信息的采集,具体代码如下:1publicvoidonSensorChanged(SensorEventevent){2float[]values=event.values;3intsensorType=event.sensor.getType();4StringBuildersb=null;5if(sensorType==Sensor.TYPE_PROXIMITY){6longcurrentTime=SystemClock.elapsedRealtime();7longspaceTime=currentTime-lastTime;8lastTime=currentTime;9if(spaceTime>800){10if(count!=-1){11.6健身实时计数的实现11mp=MediaPlayer.create(this,R.raw.refreshing_sound);12mp.start();13}14++count;15Stringtotalstr=preferences.getString("total",null);16totalTV.setText(String.valueOf(1+(int)Integer.parseInt(totalstr)));17editor.putString("total",totalTV.getText().toString());18 mit();19countTV.setText(String.valueOf(count));20}21}22}11.6健身实时计数的实现第3行代码用于获取传感器类型。第5行代码用于判断触发的传感器类型,是否是接近传感器。第6行代码用于获取系统时钟。第7行代码用于记录传感器两次触发之间的间隔时间。第11、12行用于提示俯卧撑一个动作的完成。第14行代码用于对俯卧撑数据的自增。第15~19行代码用于处理数据的记录与显示。11.7计时器的实现健身者在做运动时需要进行计时,所以开发了Android计时器功能。Android的计时器考虑到线程安全问题,不允许在线程中执行UI线程,在Android中有一个很有意思的类android.os.Handler,这个类可以实现各处线程间的消息传递。下面代码实例化了一个Handler,Handler可以通过Message在多个线程通讯,我这里做的是mlCount定时变量每次加1,然后以一定的时间格式,显示到控件tvTime上(UI线程上的操作)。计时器功能关键代码:11.7计时器的实现1handler=newHandler(){2publicvoidhandleMessage(Messagemsg){3//TODOAuto-generatedmethodstub4switch(msg.what){5case1:6mlCount++;7inttotalSec=0;8intyushu=0;9if(SETTING_SECOND_ID==settingTimerUnitFlg){10totalSec=(int)(mlCount);11}elseif(SETTING_100MILLISECOND_ID==settingTimerUnitFlg){12totalSec=(int)(mlCount/10);13yushu=(int)(mlCount%10);14}11.7计时器的实现15intmin=(totalSec/60);16intsec=(totalSec%60);17try{18if(SETTING_SECOND_ID==settingTimerUnitFlg){19tvTime.setText(String.format("%1$02d:%2$02d",min,sec));20}elseif(SETTING_100MILLISECOND_ID==settingTimerUnitFlg){21tvTime.setText(String.format("

温馨提示

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

评论

0/150

提交评论