本系列教程將分爲兩部分,第一部分是指導用戶使用Mapview控件進行編程,其中包括瞭如何得到Google Map API,如何使用該API進行簡單的開發,如何得到用戶當前所在的位置。第二部分則包括如何在地圖上,用第三方的組件庫,實現氣球式顯示若干指定位置的功能。html
步驟1 建立新的Android 工程java
首先打開eclipse新創建一個Android 工程,其中相關參數設置以下:android
Project name:MallFindergit
Build Target: Google APIs Platform – 2.1 API Level 7編程
Application Name: Mall Finderapi
Package Name: com.shawnbe.mallfinder安全
Create Activity: MallFinderActivityapp
MinimumSDK: 7eclipse
以下圖所示:ide
步驟2 註冊Google Map API key
因爲在使用google map的時候,須要使用google map api的key,所以須要先註冊一個開發者key,能夠到以下地址進行註冊:http://code.google.com/android/add-ons/google-apis/mapkey.html ,其中須要咱們先產生開發期間的md5 密紋才能完成註冊,所以咱們先學習如何生成一個MD5密紋。
咱們須要使用keytool工具,不使用傳統的命令行方式下那枯燥的證書籤名生成辦法,而是直接在eclipse下經過插件進行完成,詳細見步驟3
步驟3 安裝keytool插件
在eclipse的Help菜單中,以下圖,選擇安裝新軟件:
在安裝地址中輸入以下地址:http://www.keytool.sourceforge.net/update ,以下圖
接下來會加載相關的安裝程序,並顯示用戶協議,選擇接受全部用戶協議後進行安裝,安裝成功後從新啓動eclipse便可生效。
步驟4 產生開發期間的MD5密鑰
在從新啓動eclipse後,會發現工具欄多了以下圖的keytool菜單
如今,咱們打開debug.keystore,注意其位置回因操做系統不一樣而有不一樣
Windows Vista : C:\Users\\.android\debug.keystore
Windows XP : C:\Documents and Settings\\.android\debug.keystore
OS X 和 Linux : ~/.android/debug.keystore
點keytool菜單中,選擇open keystore,根據提示,選擇當前系統所在的debug.keystore位置並打開,以下圖,
其中,輸入密碼默認爲android便可,並點Load加載。以後會在eclipse中出現新的keytool的視圖,以下圖所示:
雙擊打開androiddebugkey,複製其md5密紋,而後訪問頁面
http://code.google.com/android/maps-api-signup.html ,接受其協議,將md5密紋複製進去,再點Generate API Key,即產生google map的api key,記得保存好這個KEY,在接下來的步驟中要使用。
步驟5 增長MapView控件
接下來,咱們能夠往佈局文件中增長MapView控件。咱們在main.xml中添加以下代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="你的GOOGLE MAP API KEY "/>
</FrameLayout>
</LinearLayout>
在這個控件中,請注意要在android:apiKey的位置填入剛申請的google map api key。
步驟6 設置相關的權限
因爲咱們的應用須要調用Google Map的數據,以及經過手機的GPS得到相關的其餘地理位置數據,所以咱們必須在Android的Manifest文件中進行權限的設置。
咱們打開AndroidManifest.xml文件,而後增長以下代碼所示的權限設置,注意添加在標籤後,但要在標籤前。
<uses-feature android:name="android.hardware.location.gps"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/>
在這裏,咱們分別調用了gps位置服務權限,使用互聯網的權限以及使用最佳位置查找的權限(FINE_LOCATION)。在本文中,其實沒用到FINE_LOCATION,但只是告訴開發者能夠調整使用不一樣的地理位置提供者(providers)以提供準確的位置服務,若是要有比較精確的地理位置服務,那麼能夠設置android.permisson.ACCESS_FINE_LOCATION服務。要注意的是在開發中,不要過多引用一些不須要使用的權限設置,不然會給用戶帶來擔心安全等問題。要是隻想調用通常的位置服務,可使用普通的android.permission.ACCESS_COARSE_LOCATION權限。
爲了在應用中使用Google Map,須要在Manifest文件中包含相關的類庫文件,因此加入以下代碼:
<uses-library android:required="true" android:name="com.google.android.maps" />
爲了視覺的美觀,咱們把標題欄也去掉,以便留給地圖更大的空間,因此設置爲
android:theme="@android:style/Theme.NoTitleBar"
下面是完整的Manifest文件代碼:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.shawnbe.mallfinder"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
<activity
android:label="@string/app_name"
android:name=".MallFinderActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:required="true" android:name="com.google.android.maps" />
</application>
<uses-feature android:name="android.hardware.location.gps"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
步驟7 設置MapView
下面對主activity程序(MallFinderActivity.java)進行修改,首先讓其繼承MapActivity類,以下:
public class MallFinderActivity extends MapActivity {
因爲繼承了MapActivity類,所以必須實現isRouteDisplayed方法,這個方法是用來作路線導航用的,這裏咱們不須要,所以只須要簡單返回false便可:
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
接下來咱們就能夠聲明MapController控件,並對其進行相關屬性的設置了,首先是聲明控件
private MapController mapController;
private MapView mapView;
並在oncreate方法中進行屬性設置以下:
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setSatellite(false);
mapView.setStreetView(true);
mapController = mapView.getController();
mapController.setZoom(13);
在上面的代碼中,設置了地圖顯示的方式爲街道模式(經過設置mapview的setStreetView屬性值爲true),而且經過mapView.setBuiltInZoomControls(true); 使用了系統內置的放大縮小功能,並設置了地圖的放大縮小倍數爲13。
這個時候咱們就能夠選擇運行應用,看下是否符合咱們的初步預期效果,運行後效果以下圖:
步驟8 得到當前所在位置
在LBS應用中,十分重要的工做是要得到當前設備所在的位置,這個可使用locationManager類實現,在得到當前位置的時候是須要花費一些時間的。咱們繼續聲明兩個參數變量以下:
private LocationManager locationManager;
private GeoPoint currentLocation;
分別聲明瞭LocationManager類的實例和GeoPoint類的實例(用於下文中的經緯度的計算)。
再增長以下幾個方法:
public void getLastLocation(){
String provider = getBestProvider();
currentLocation = locationManager.getLastKnownLocation(provider);
if(currentLocation != null){
setCurrentLocation(currentLocation);
}
else
{
Toast.makeText(this, "Location not yet acquired", Toast.LENGTH_LONG).show();
}
}
public void animateToCurrentLocation(){
if(currentPoint!=null){
mapController.animateTo(currentPoint);
}
}
public String getBestProvider(){
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
criteria.setAccuracy(Criteria.NO_REQUIREMENT);
String bestProvider = locationManager.getBestProvider(criteria, true);
return bestProvider;
}
public void setCurrentLocation(Location location){
int currLatitude = (int) (location.getLatitude()*1E6);
int currLongitude = (int) (location.getLongitude()*1E6);
currentLocation = new GeoPoint(currLatitude,currLongitude);
currentLocation = new Location("");
currentLocation.setLatitude(currentPoint.getLatitudeE6() / 1e6);
currentLocation.setLongitude(currentPoint.getLongitudeE6() / 1e6);
}
而且在oncreate方法中,添加對以上方法的調用代碼以下:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setSatellite(false);
mapView.setStreetView(true);
mapController = mapView.getController();
mapController.setZoom(13);
getLastLocation();
animateToCurrentLocation();
}
首先,在getLastLocation這個方法中,建立了locationManager類的實例而且根據設置的條件返回一個合適的地理位置提供方法。在這裏,咱們並無指定對地理位置提供者的查詢條件,在實際應用中,開發者能夠經過設置criteria.setAccuracy()和criteria.setPowerRequirement()方法進行查找。若是要使用最精確的provider的話,能夠設置使用ACCURACY_FINE方法進行搜索,以下代碼所示:
criteria.setAccuracy(Criteria.ACCURACY_FINE);
在本文中之因此不選擇使用最準確的位置provider主要是由於是沒在室外進行測試,都是在室內調試程序,建議開發完後換成GPS模式provider到室外進行調試那樣將看到很好的效果。
接下來代碼中使用 currentLocation = locationManager.getLastKnownLocation(provider); 一句,得到最新的位置信息,而且在setCurrentLocation方法中,對經過prodiver得到的地理位置信息Location對象進行經緯度的轉換爲GeoPoint對象。而後調用animateToCurrentLocation方法,將地圖的中心點定位到咱們當前的位置上去。
此外,因爲咱們的位置是會發生變化的,因此須要使用location 監聽器去檢測咱們的位置變化,這時須要實現locationListener接口,以下所示:
public class MallFinderActivity extends MapActivity implements LocationListener{
同時咱們須要實現LocationListener類的如下幾個方法:
@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
其中這裏咱們關心的是須要實現onLocationChanged方法,這裏咱們調用以前編寫好的setlocation方法,得到當前的最新位置,以下:
@Override
public void onLocationChanged(Location newLocation) {
// TODO Auto-generated method stub
setCurrentLocation(newLocation);
}
爲了完善程序,在程序處在onResume及onPause狀態下都能及時更新地理位置信息以及取消更新,加上以下代碼:
@Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(getBestProvider(), 1000, 1, this);
}
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
小結
在本系列的第一講中,分步講解了如何註冊Google API KEY以及Mapview控件基本方法的使用,還有讓讀者瞭解到使用google map的初步步驟,在下一講中,將指導讀者如何對地圖上的位置進行標註。
本系列教程將分爲兩部分,第一部分是指導用戶使用Mapview控件進行編程,其中包括瞭如何得到Google Map API,如何使用該API進行簡單的開發,如何得到用戶當前所在的位置。第二部分則包括如何在地圖上,用第三方的組件庫,實現氣球式顯示若干指定位置的功能。
步驟1 建立新的Android 工程
首先打開eclipse新創建一個Android 工程,其中相關參數設置以下:
Project name:MallFinder
Build Target: Google APIs Platform – 2.1 API Level 7
Application Name: Mall Finder
Package Name: com.shawnbe.mallfinder
Create Activity: MallFinderActivity
MinimumSDK: 7
以下圖所示:
步驟2 註冊Google Map API key
因爲在使用google map的時候,須要使用google map api的key,所以須要先註冊一個開發者key,能夠到以下地址進行註冊:http://code.google.com/android/add-ons/google-apis/mapkey.html ,其中須要咱們先產生開發期間的md5 密紋才能完成註冊,所以咱們先學習如何生成一個MD5密紋。
咱們須要使用keytool工具,不使用傳統的命令行方式下那枯燥的證書籤名生成辦法,而是直接在eclipse下經過插件進行完成,詳細見步驟3
步驟3 安裝keytool插件
在eclipse的Help菜單中,以下圖,選擇安裝新軟件:
在安裝地址中輸入以下地址:http://www.keytool.sourceforge.net/update ,以下圖
接下來會加載相關的安裝程序,並顯示用戶協議,選擇接受全部用戶協議後進行安裝,安裝成功後從新啓動eclipse便可生效。
步驟4 產生開發期間的MD5密鑰
在從新啓動eclipse後,會發現工具欄多了以下圖的keytool菜單
如今,咱們打開debug.keystore,注意其位置回因操做系統不一樣而有不一樣
Windows Vista : C:\Users\\.android\debug.keystore
Windows XP : C:\Documents and Settings\\.android\debug.keystore
OS X 和 Linux : ~/.android/debug.keystore
點keytool菜單中,選擇open keystore,根據提示,選擇當前系統所在的debug.keystore位置並打開,以下圖,
其中,輸入密碼默認爲android便可,並點Load加載。以後會在eclipse中出現新的keytool的視圖,以下圖所示:
雙擊打開androiddebugkey,複製其md5密紋,而後訪問頁面
http://code.google.com/android/maps-api-signup.html ,接受其協議,將md5密紋複製進去,再點Generate API Key,即產生google map的api key,記得保存好這個KEY,在接下來的步驟中要使用。
步驟5 增長MapView控件
接下來,咱們能夠往佈局文件中增長MapView控件。咱們在main.xml中添加以下代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="你的GOOGLE MAP API KEY "/>
</FrameLayout>
</LinearLayout>
在這個控件中,請注意要在android:apiKey的位置填入剛申請的google map api key。
步驟6 設置相關的權限
因爲咱們的應用須要調用Google Map的數據,以及經過手機的GPS得到相關的其餘地理位置數據,所以咱們必須在Android的Manifest文件中進行權限的設置。
咱們打開AndroidManifest.xml文件,而後增長以下代碼所示的權限設置,注意添加在標籤後,但要在標籤前。
<uses-feature android:name="android.hardware.location.gps"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/>
在這裏,咱們分別調用了gps位置服務權限,使用互聯網的權限以及使用最佳位置查找的權限(FINE_LOCATION)。在本文中,其實沒用到FINE_LOCATION,但只是告訴開發者能夠調整使用不一樣的地理位置提供者(providers)以提供準確的位置服務,若是要有比較精確的地理位置服務,那麼能夠設置android.permisson.ACCESS_FINE_LOCATION服務。要注意的是在開發中,不要過多引用一些不須要使用的權限設置,不然會給用戶帶來擔心安全等問題。要是隻想調用通常的位置服務,可使用普通的android.permission.ACCESS_COARSE_LOCATION權限。
爲了在應用中使用Google Map,須要在Manifest文件中包含相關的類庫文件,因此加入以下代碼:
<uses-library android:required="true" android:name="com.google.android.maps" />
爲了視覺的美觀,咱們把標題欄也去掉,以便留給地圖更大的空間,因此設置爲
android:theme="@android:style/Theme.NoTitleBar"
下面是完整的Manifest文件代碼:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.shawnbe.mallfinder"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
<activity
android:label="@string/app_name"
android:name=".MallFinderActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:required="true" android:name="com.google.android.maps" />
</application>
<uses-feature android:name="android.hardware.location.gps"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
步驟7 設置MapView
下面對主activity程序(MallFinderActivity.java)進行修改,首先讓其繼承MapActivity類,以下:
public class MallFinderActivity extends MapActivity {
因爲繼承了MapActivity類,所以必須實現isRouteDisplayed方法,這個方法是用來作路線導航用的,這裏咱們不須要,所以只須要簡單返回false便可:
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
接下來咱們就能夠聲明MapController控件,並對其進行相關屬性的設置了,首先是聲明控件
private MapController mapController;
private MapView mapView;
並在oncreate方法中進行屬性設置以下:
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setSatellite(false);
mapView.setStreetView(true);
mapController = mapView.getController();
mapController.setZoom(13);
在上面的代碼中,設置了地圖顯示的方式爲街道模式(經過設置mapview的setStreetView屬性值爲true),而且經過mapView.setBuiltInZoomControls(true); 使用了系統內置的放大縮小功能,並設置了地圖的放大縮小倍數爲13。
這個時候咱們就能夠選擇運行應用,看下是否符合咱們的初步預期效果,運行後效果以下圖:
步驟8 得到當前所在位置
在LBS應用中,十分重要的工做是要得到當前設備所在的位置,這個可使用locationManager類實現,在得到當前位置的時候是須要花費一些時間的。咱們繼續聲明兩個參數變量以下:
private LocationManager locationManager;
private GeoPoint currentLocation;
分別聲明瞭LocationManager類的實例和GeoPoint類的實例(用於下文中的經緯度的計算)。
再增長以下幾個方法:
public void getLastLocation(){
String provider = getBestProvider();
currentLocation = locationManager.getLastKnownLocation(provider);
if(currentLocation != null){
setCurrentLocation(currentLocation);
}
else
{
Toast.makeText(this, "Location not yet acquired", Toast.LENGTH_LONG).show();
}
}
public void animateToCurrentLocation(){
if(currentPoint!=null){
mapController.animateTo(currentPoint);
}
}
public String getBestProvider(){
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
criteria.setAccuracy(Criteria.NO_REQUIREMENT);
String bestProvider = locationManager.getBestProvider(criteria, true);
return bestProvider;
}
public void setCurrentLocation(Location location){
int currLatitude = (int) (location.getLatitude()*1E6);
int currLongitude = (int) (location.getLongitude()*1E6);
currentLocation = new GeoPoint(currLatitude,currLongitude);
currentLocation = new Location("");
currentLocation.setLatitude(currentPoint.getLatitudeE6() / 1e6);
currentLocation.setLongitude(currentPoint.getLongitudeE6() / 1e6);
}
而且在oncreate方法中,添加對以上方法的調用代碼以下:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setSatellite(false);
mapView.setStreetView(true);
mapController = mapView.getController();
mapController.setZoom(13);
getLastLocation();
animateToCurrentLocation();
}
首先,在getLastLocation這個方法中,建立了locationManager類的實例而且根據設置的條件返回一個合適的地理位置提供方法。在這裏,咱們並無指定對地理位置提供者的查詢條件,在實際應用中,開發者能夠經過設置criteria.setAccuracy()和criteria.setPowerRequirement()方法進行查找。若是要使用最精確的provider的話,能夠設置使用ACCURACY_FINE方法進行搜索,以下代碼所示:
criteria.setAccuracy(Criteria.ACCURACY_FINE);
在本文中之因此不選擇使用最準確的位置provider主要是由於是沒在室外進行測試,都是在室內調試程序,建議開發完後換成GPS模式provider到室外進行調試那樣將看到很好的效果。
接下來代碼中使用 currentLocation = locationManager.getLastKnownLocation(provider); 一句,得到最新的位置信息,而且在setCurrentLocation方法中,對經過prodiver得到的地理位置信息Location對象進行經緯度的轉換爲GeoPoint對象。而後調用animateToCurrentLocation方法,將地圖的中心點定位到咱們當前的位置上去。
此外,因爲咱們的位置是會發生變化的,因此須要使用location 監聽器去檢測咱們的位置變化,這時須要實現locationListener接口,以下所示:
public class MallFinderActivity extends MapActivity implements LocationListener{
同時咱們須要實現LocationListener類的如下幾個方法:
@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
其中這裏咱們關心的是須要實現onLocationChanged方法,這裏咱們調用以前編寫好的setlocation方法,得到當前的最新位置,以下:
@Override
public void onLocationChanged(Location newLocation) {
// TODO Auto-generated method stub
setCurrentLocation(newLocation);
}
爲了完善程序,在程序處在onResume及onPause狀態下都能及時更新地理位置信息以及取消更新,加上以下代碼:
@Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(getBestProvider(), 1000, 1, this);
}
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
小結
在本系列的第一講中,分步講解了如何註冊Google API KEY以及Mapview控件基本方法的使用,還有讓讀者瞭解到使用google map的初步步驟,在下一講中,將指導讀者如何對地圖上的位置進行標註。