智能手机正在逐渐统治整个手机世界,这是一个显而易见的事实。自从GPS设备被普遍的内嵌到智能手机中,它给那些利用地理定位的应用程序提供了极大的帮助。 其中一类程序是采用基于定位的服务(Location Based Service),它是利用数据来计算用户所在位置的。程序通常用的技术是geocoding(从地理数据中寻找相关的地理坐标,如一条街的位置)和reverse geocoding(根据提供的坐标来提供信息)。另一类程序则采用Proximity Alerts。像它的名字那样,当用户的位置接近某个特定的Point of Interest(POI)时会进行提示。随着大量的程序打算应用这项技术,并伴有宣传精彩的示例,Proximity alert将会是接下来几年的热点。在这个教程中,我将展示怎样去利用Android的内嵌Proximity alert功能。 在开始之前,简单的了解一下基于定位的程序或geocoding会对接下来的阅读带来极大的帮助。你可能需要要读一下我之前的几篇教程,如 “Android Location Based Services Application – GPS location”和“Android Reverse Geocoding with Yahoo API – PlaceFinder”。另一个需要提醒的是,这篇教程是受“Developing Proximity Alerts for Mobile Applications using the Android Platform”这篇文章启发而生。 这篇文章分为四个部分,对于初学者一些地方可能会稍显复杂并带来一些困难。基于这些原因,我决定写一篇相对更短更易懂的教程。 我们将会创建一个简单的程序,它存储的一个点坐标会被用户触发并且当用户接近这个点推送消息。 当用户到达那个点坐标时会根据需求获取消息。 我们首先创建一个Eclipse项目开始,并命名为“AndroidProximityAlertProject”。接下来,为程序创建一个Main Activity然后命名为ProxAlertActivity。 下面是程序的主页面: 这里是UI界面的布局,命名为main.xml
现在我们开始做一些有意思的东西。首先,我们需要一个到LocationManager class的引用,提供系统的位置服务。你可以通过getSystemService方法从activity中获得。然后,(如果用户的位置发生改变)可以通过requestLocationUpdates方法来获得通知。在开发Proximity Alerts的时候,这并不是必须的要求,但是在这里我需要用它计算POI和用户位置之间的距离。在我们的示例中,设备在任何时候都可以调用getLastKnownLocation方法获取某个指定提供者的最后位置。最后,我们会用到addProximityAlert方法设定一个proximity alert。它可以指定你想要坐标(纬度、经度)和半径。 如果我们想要在一段特定的时间监视某个alert,还可以给那个alert设置过期时间。我们还可以提供PendingIntent,当设备进入或者离开一个监测到的alert区域时发出intent。 示例代码如下:
在onCreate方法中,我们用了location manager并加入一个自定义类,它实现了LocatioListener接口。可以让我们通过onLocationChanged方法得到位置变换的通知。接下来,看一下怎样去处理更新。我们会使用不同的UI控件给按钮添加onClickListeners。 当用户想要得到目前的坐标时,populateCoordinatesFromLastKnownLocation方法会被调用。在方法内部,使用getLastKnownLocation方法来得到Location对象,位置信息将会被填充到EditText控件。 同样的,当位置信息第一次被获取时,用户想要保存坐标并向saveProxityAlertPoint提供alert(添加POI)。我们可以将经度和纬度以preference data的方式用SharedPreferences类来保存下来,详情请见SharedPreferences.Editor。最后,我们通过getBrodcast静态方法来创建一个PendingIntent。对于这种封装过的intent,我们创建一个intentFilter并使用registerReceiver方法来绑定一个自定义BroadcastReceiver和intentfiler。需要提醒的是,这种绑定还可以通过manifest来实现。 现在,我们来看一下如何来处理用户位置变化。在实现接口的MyLocationListener类里,我们从SharedPreference里获取存储的位置信息(retrievelocationFromPreferences)。然后,通过distranceTo方法计算两个位置(POI和现在位置)的距离。通过这个计算,我们才会知道是否真正进入了某个区域。 第一步,处理进入POI事件。 可以通过继承BroadcastReceiver的类(ProximityIntentReceiver)来实现。当proximity alert被触发,会返回一个自定义intent(之前绑定的locationManager)。处理过程发生在onReceive方法里,它会被事件(进出POI区域)调用。在方法内部,我们从相关intent获取KEY_PROXIMITY_ENTERING key(用来定义proximity alert类型是进入-true,还是离开-false))。 示例代码如下:
代码简洁明了。当我们定义了一个进入或离开的proximity alert,就可以提供一个自定义的推送了。要实现它,首先需要引用一个合适的Service,比如NotificationMananger。通过这个Service,我们发送通知给用户,并封装合适的推送对象。推送的方式是可定制的,如包括震动或者闪光灯等。我们还可以添加特定的图标在状态栏显示。如果只是简单添加标题和信息,适合调用setLastestEventInfo方法。 你可以在这里查看关于notification的详细内容。除此之外,我们可以通过PendingIntent来引导Activity进行下意识地点击推送。 为了让代码更通俗易懂,这里我就不这样做了。 我们最后得到的manifest代码如下:
别忘了,添加相应的Permission到Manifest里: 现在可以测试我们的程序了。启动Eclipse配置,然后跳转到DDMS界面查看Emulation Control标签,可以发现一个Location Controls选项。它可以给模拟器发送模拟的位置数据。在Manual标签里,点击Send按钮,这样就能生成一些坐标。 在此之后,GPS提供者将会知道最后一次请求的已知位置。所以,点击“find Coordinates”按钮你将会得到: 点击“Save Point”来声明当前位置为POI。 当前位置坐标会被保存到SharedPreference并且Proximity Alert会被添加到location manager中。 接下来,让我们模拟用户接近指定位置的事件。我们会更改坐标值,例如更改维度(从37.422006到37.522006)。现在我们离的POI很远。现在我们假装我们正在接近它,所以把坐标改的近一点(从37,52206到37.423006)。 当两点之间的半径达到预警要求(之前设置为1000米)时会得到提示。这时,创建并通过notification manager推送消息。推送的消息如下: 好了,大功告成。本文通过一个简单的示例介绍了如何使用Android Platform来实施Proximity alerts。你可以从这里下载示例项目的Eclipse项目代码。 本文由 伯乐在线 - gagayu 翻译自 javacodegeeks。欢迎加入Android小组。转载请参见文章末尾处的要求。 |