您的位置:首页 > 移动开发 > Android开发

Android 的 Mapview & Location 使用教程

2013-09-02 21:32 381 查看
本教程将探讨如何使用谷歌地图API来显示出信息点(POI),并使用手机提供的定位服务,来显示当前位置可搜索到的POI位置。这种情况下,我们应使用商场作为POI。



我把教程分为了两部分。

第一部分(在本节中)将介绍包括:

1.MapView对象的使用

2.使用MD5密文获取一个谷歌地图API密钥

3.实现一个地点监听器,以获得你的当前位置

第二部分将包括:

1.在应用程序中使用外部库类

2.创建显示出你的当前位置和周边的信息点

现在让我们开始吧!


步骤1:创建一个新的Android项目

启动EclipseIDE并创建一个新的Android项目。

File>Create>NewAndroidProject

使用以下设置创建新的项目:

项目名称:MallFinder

生成目标:GoogleAPIsPlatform–2.1APILevel7

应用程序名:MallFinder

包名称:com.shawnbe.mallfinder

创建Activity:MallFinderActivity

最低SDK版本:7





设置完成后,点击完成。



步骤2:在谷歌上注册获取API密钥

因为MapView对象使用谷歌地图,你需要在谷歌注册一个API密钥,并同意服务条款,然后才可以使用他们。注册过程相当简单。想要了解更多关于获得地图API密钥信息,请查看此链接。

要对你的应用程序进行签名就必须要用到的MD5密文生成的API秘钥,听起来很令人困惑,但它并不难,因为你会发现它像当我们之前的几个步骤。而不是上面的链接所述,使用命令行的方式得到你的MD5密文,我们将使用keytool的一个Eclipse插件。想要了解更多有关keytool的插件信息,请查看此链接。



步骤3:安装keytool插件

在EclipseIDE中,导航到Help>InstallNewSoftware。





当新的窗口弹出,在窗口的顶部点击“Add”按钮。

在“Name”栏输入“keytool”(不含引号),

在“Location”栏输入“http://www.keytool.sourceforge.net/update”





点击“OK”。

经过短暂的加载时间,窗口将出现一个标有“keytool”的复选框。选中该复选框并单击“下一步”。同意协议的条款,然后单击“下一步”完成。

注意:在安装过程中,可能会提示您确定是否信任安全证书。如果你确定,就选中复选框并单击“确定”继续安装。





安装完成后,将会提示重新启动Eclipse。



步骤4:获取MD5密文

Eclipse重新启动之后,你应该看到一个新的菜单项“keytool”,它旁边有一个小钥匙图标。





我们现在要打开调试的keystore。

注意:由于操作系统的位置可能会有所不同。各种操作系统的默认位置:

WindowsVista:C:\Users\\.android\debug.keystore
WindowsXP:C:\DocumentsandSettings\\.android\debug.keystore
OSXandLinux:~/.android/debug.keystore

点击keytool菜单项>打开密钥库。

点击位于“文件名”文本框右侧的“浏览”按钮,并找到keystore的位置(上述为默认位置),并选择debug.keystore文件。

单击“打开”,选择类型“android”(不带引号),这是默认的调试密码,然后单击“Load”。





现在应该在屏幕底部的面板可见一个新的keytool的标签(如果你没有看到它,导航到“Window>OpenPerspective>JavaBrowsing”)。





点击debug.keystore路径左侧的小箭头将显示androiddebugkey。

双击androiddubugkey并复制MD5密文。

打开Web浏览器,进入以下网址。http://code.google.com/android/maps-api-signup.html

阅读并同意条款,在文本框中输入MD5密文,并点击“GenerateAPIKey”。请注意保存好你的API密钥,因为使用MapView的时候需要它。


步骤5:在布局中添加MapView

在这一步,我们将添加一个MapView到布局文件。
打开位于MallFinder>res>layout>main.xml中的main.xml文件,并修改该文件如下所示,包括一个FrameLayout和MapView:

01
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
02
03
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
04
android:layout_width
=
"fill_parent"
05
android:layout_height
=
"fill_parent"
06
android:orientation
=
"vertical"
>
07
<
FrameLayout
08
android:layout_width
=
"fill_parent"
09
10
android:layout_height
=
"fill_parent"
>
11
<
com.google.android.maps.MapView
12
android:id
=
"@+id/mapView"
13
android:layout_width
=
"fill_parent"
14
android:layout_height
=
"fill_parent"
15
android:clickable
=
"true"
16
17
android:apiKey
=
"PUT
YOURAPIKEYHERE"
/>
18
</
FrameLayout
>
19
</
LinearLayout
>
上述布局在整个可用的屏幕空间创建一个MapView。在当前状态下运行的应用程序,将导致在强制关闭。我们还需要完成多个步骤。


步骤6:设置权限,并导入所需的库

由于我们的应用程序将会从GoogleMaps下载数据,同时需要从手机的GPS或其他定位服务访问信息,所以我们需要在AndroidManifest文件中的声明必要的权限来使用这些服务。

要做到这一点,打开位于MallFinder>AndroidManifest.xml中的AndroidManifest.xml文件。

在关闭应用程序标记(</application>)后面,和在闭幕清单标记(</manifest>)之前添加以下几行。

1
<
uses-feature
android:name
=
"android.hardware.location.gps"
/>
2
3
<
uses-permission
android:name
=
"android.permission.ACCESS_FINE_LOCATION"
/>
4
<
uses-permission
android:name
=
"android.permission.INTERNET"
/>
在这个例子中,我不需要FINE_LOCATION,但我已经包含在此,我想你可能要调整你的代码来测试各种提供商,如果你想获得更准确的位置,你将需要FINE_LOCATION权限。通常任何生产中的应用程序都不应该声明不需要的权限。如你要求更多的权限,这是一个非常糟糕的做法,使用户警惕你的应用程序。如果你不打算使用更准确的供应商,你可以不声明android.permission.ACCESS_COARSE_LOCATION。

为了在我们的MapView中使用谷歌地图,我们需要在Manifest文件中声明该库,这样我们要在关闭活动标记和关闭应用程序标记代码之间加入下面的标签:

1
<
uses-library
android:required
=
"true"
android:name
=
"com.google.android.maps"
/>
我们可以把标题栏去掉,因为我觉得这是不必要的。它使用了太多我们有限的屏幕空间。在应用程序删除标题栏添加下面代码:

1
android:theme="@android:style/Theme.NoTitleBar"
现在我们完整的Manifest文件看起来像这样:

01
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
02
03
<
manifest
xmlns:android
=
"http://schemas.android.com/apk/res/android"
04
package
=
"com.shawnbe.mallfinder"
05
android:versionCode
=
"1"
06
android:versionName
=
"1.0"
>
07
<
uses-sdk
android:minSdkVersion
=
"7"
/>
08
09
<
application
10
android:icon
=
"@drawable/ic_launcher"
11
android:label
=
"@string/app_name"
12
android:theme
=
"@android:style/Theme.NoTitleBar"
>
13
<
activity
14
android:label
=
"@string/app_name"
15
android:name
=
".MallFinderActivity"
>
16
17
<
intent-filter
>
18
<
action
android:name
=
"android.intent.action.MAIN"
/>
19
20
<
category
android:name
=
"android.intent.category.LAUNCHER"
/>
21
</
intent-filter
>
22
23
</
activity
>
24
<
uses-library
android:required
=
"true"
android:name
=
"com.google.android.maps"
/>
25
</
application
>
26
<
uses-feature
android:name
=
"android.hardware.location.gps"
/>
27
28
<
uses-permission
android:name
=
"android.permission.ACCESS_FINE_LOCATION"
/>
29
<
uses-permission
android:name
=
"android.permission.INTERNET"
/>
30
</
manifest
>


步骤7:设置MapView

在我们运行MapView之前,我们还需要做一些MallFinderActivity类的调整。

打开的主要活动类(MallFinderActivity.java),这是位于:MallFinder>src>com.shawnbe.mallfinder>MallFinderActivity.java

在我们的应用程序中,我们需要将这个类继承“MapActivity”,而不是“Activity”。

修改行:

1
public
class
MallFinderActivity
extends
Activity
{
改成:

1
public
class
MallFinderActivity
extends
MapActivity
{
继承MapActivity类时,我们需要实现
isRouteDisplayed()
方法,所以我们需要添加下面的方法:

1
@Override
2
protected
boolean
isRouteDisplayed()
{
3
//
TODOAuto-generatedmethodstub
4
return
false
;
5
}
这时,我们可以启动应用程序并显示MapView,但我们的没有设置选项,如缩放级别和可见图层。我们开始在onCreate方法中声明以下变量:

1
private
MapController
mapController;
2
private
MapView
mapView;
onCreate
方法中添加以下几行代码:

1
mapView
=(MapView)findViewById(R.id.mapView);
2
mapView.setBuiltInZoomControls(
true
);
3
mapView.setSatellite(
false
);
4
mapView.setStreetView(
true
);
5
mapController
=mapView.getController();
6
mapController.setZoom(
13
);
上面的代码只显示街层并隐藏的卫星层。我个人喜好选择它,因为我觉得在这种情况下更容易读。正如你喜欢用布尔值false和true来随意调整一样。此外,缩放级别设置为13,你也可以调整到1作为整个世界视图来看和20最大变焦。

最后,我们可以继续启动应用程序,以确保一切运行像预期一样。

有几种方法来运行应用程序,首先:

在PackageExplorerwindow中右键单击项目>Runas>AndroidApplication

或者

从菜单上,单击Run>Run





然后选择你的手机或模拟器。你应该可以看到一个地图覆盖整个屏幕,除了在屏幕上方的通知栏,而且可以滚动并使用缩放。





步骤8:获取你当前的位置

要获得你的当前位置,我们
使用
locationManager类,它允许应用程序获取设备的位置。此过程可能需要一些时间来定位当前位置,因此,建议使用你
lastKnownLocation,直到你可以得到一个更准确的当前的位置。

再声明以下两个变量在步骤7中:

1
private
LocationManager
locationManager;
2
private
GeoPoint
currentLocation;
此外,将以下方法添加到
MallFinderActivity.java
类:

01
public
void
getLastLocation(){
02
String
provider=getBestProvider();
03
currentLocation
=locationManager.getLastKnownLocation(provider);
04
if
(currentLocation
!=
null
){
05
setCurrentLocation(currentLocation);
06
}
07
else
08
{
09
Toast.makeText(
this
,
"Location
notyetacquired"
,
Toast.LENGTH_LONG).show();
10
}
11
}
12
13
public
void
animateToCurrentLocation(){
14
if
(currentPoint!=
null
){
15
mapController.animateTo(currentPoint);
16
}
17
}
18
19
public
String
getBestProvider(){
20
locationManager
=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
21
Criteria
criteria=
new
Criteria();
22
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
23
criteria.setAccuracy(Criteria.NO_REQUIREMENT);
24
String
bestProvider=locationManager.getBestProvider(criteria,
true
);
25
return
bestProvider;
26
}
27
28
public
void
setCurrentLocation(Location
location){
29
int
currLatitude
=(
int
)
(location.getLatitude()*1E6);
30
int
currLongitude
=(
int
)
(location.getLongitude()*1E6);
31
currentLocation
=
new
GeoPoint(currLatitude,currLongitude);
32
33
currentLocation
=
new
Location(
""
);
34
currentLocation.setLatitude(currentPoint.getLatitudeE6()
/1e6);
35
currentLocation.setLongitude(currentPoint.getLongitudeE6()
/1e6);
36
}
在onCreate方法中添加以下两行:

1
getLastLocation();
2
animateToCurrentLocation();
onCreate方法现在看起来:

01
public
void
onCreate(Bundle
savedInstanceState){
02
super
.onCreate(savedInstanceState);
03
setContentView(R.layout.main);
04
mapView
=(MapView)findViewById(R.id.mapView);
05
mapView.setBuiltInZoomControls(
true
);
06
mapView.setSatellite(
false
);
07
mapView.setStreetView(
true
);
08
mapController
=mapView.getController();
09
mapController.setZoom(
13
);
10
getLastLocation();
11
animateToCurrentLocation();
12
}
getLastLocation方法创建的locationManager类的实例,这是基于最好的供应商使用定位服务的要求。在上面的代码中,我们没有指定任何条件的供应商,但是你可以根据你的精度和功耗要求的标准来调整使用criteria.setAccuracy()和criteria.setPowerRequirement()方法。上述步骤6中,我提到,你可能需要调整你的标准,以获得更精确的的位置。如果你想做到这一点,你设置的精度标准ACCURACY_FINE的代码是:

1
criteria.setAccuracy(Criteria.ACCURACY_FINE);
我没有选择最精确的供应商(GPS)的原因是,因为我在室内测试此代码,并可能永远不会得到我位置。如果你能用GPS定位到当前位置,你随时可以改变准确性在外面测试它。

由于你的手机可能会使用不同的供应商指定的标准,这通常是GPS或网络(也可以是别的)。如果设置为currentLocation,最后知道的位置至少要等到我们得到了更准确和更新的位置。我们滚动围绕这些坐标为中心的地图才能发现当前位置的经度和纬度。

现在我们得到最后一个已知的位置,我们使用位置监听器来检测我们的位置变化来更新应用程序。要做到这一点,我们需要我们的类(MallFinderActivity.java)实现locationListener。首先,我们修改行:

1
public
class
MallFinderActivity
extends
MapActivity
{
改成:

1
public
class
MallFinderActivity
extends
MapActivity
implements
LocationListener{
实现地点监听器,需要我们重写一组方法,所以我们要添加以下标准方法如下(我指的这些标准方法,实际上并不做任何事情):

01
@Override
02
public
void
onLocationChanged(Location
arg0){
03
//
TODOAuto-generatedmethodstub
04
}
05
06
@Override
07
public
void
onProviderDisabled(String
arg0){
08
//
TODOAuto-generatedmethodstub
09
}
10
11
@Override
12
public
void
onProviderEnabled(String
arg0){
13
//
TODOAuto-generatedmethodstub
14
}
15
16
@Override
17
public
void
onStatusChanged(String
arg0,
int
arg1,
Bundlearg2){
18
//
TODOAuto-generatedmethodstub
19
}
我们将使用
onLocationChanged
的方法检测我们的位置更新,然后使用setcurrentLocation方法设置为我们当前的位置。

修改onlocationChanged的方法如下:

1
@Override
2
public
void
onLocationChanged(Location
newLocation){
3
//
TODOAuto-generatedmethodstub
4
setCurrentLocation(newLocation);
5
}
添加以下几行代码。这些方法会在每当应用程序启动或恢复的时候,请求更新;当应用程序被暂停或关闭的同时,也将停止检查更新。

01
@Override
02
protected
void
onResume()
{
03
super
.onResume();
04
locationManager.requestLocationUpdates(getBestProvider(),
1000
,
1
,
this
);
05
}
06
07
@Override
08
protected
void
onPause()
{
09
super
.onPause();
10
locationManager.removeUpdates(
this
);
11
}
如果此时运行的应用程序的MapView应围绕你最后知道的位置,当你的手机能够定位,它将会围绕你的当前位置为中心更新。由于在步骤7设置定位的精确性,得到你的位置时间长度会有所不同。

在这一节中,我们已经学会如何使用的MapView,实现locationListener,并取得你的当前位置。在下一节中,我们将扩展包括使用外部的库来处理的MapView上信息点的覆盖和使用气球弹出窗口显示一些信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐