Android定位和地圖開發(fā)實(shí)例

Android開發(fā)中地圖和定位是很多軟件不可或缺的內(nèi)容,這些特色功能也給人們帶來了很多方便。

首先介紹一下地圖包中的主要類:

MapController:? 主要控制地圖移動,伸縮,以某個(gè)GPS坐標(biāo)為中心,控制MapView中的view組件,管理Overlay,提供View的基本功能。使用多種地圖模式(地圖模式(某些城市可實(shí)時(shí)對交通狀況進(jìn)行更新),衛(wèi)星模式,街景模式)來查看Google Map。常用方法:animateTo(GeoPoint point)? setCenter(GeoPoint point)? setZoom(int zoomLevel) 等。

Mapview? : 是用來顯示地圖的view, 它派生自android.view.ViewGroup。當(dāng)MapView獲得焦點(diǎn),可以控制地圖的移動和縮放。地圖可以以不同的形式來顯示出來,如街景模式,衛(wèi)星模式等,通過setSatellite(boolean)? setTraffic(boolean), setStreetView(boolean) 方法。

Overlay:是覆蓋到MapView的最上層,可以擴(kuò)展其ondraw接口,自定義在MapView中顯示一些自己的東西。MapView通過MapView.getOverlays()對Overlay進(jìn)行管理。

Projection:MapView中GPS坐標(biāo)與設(shè)備坐標(biāo)的轉(zhuǎn)換(GeoPoint和Point)。

定位系統(tǒng)包中的主要類:

LocationManager:本類提供訪問定位服務(wù)的功能,也提供獲取最佳定位提供者的功能。另外,臨近警報(bào)功能也可以借助該類來實(shí)現(xiàn)。

LocationProvider:該類是定位提供者的抽象類。定位提供者具備周期性報(bào)告設(shè)備地理位置的功能。

LocationListener:提供定位信息發(fā)生改變時(shí)的回調(diào)功能。必須事先在定位管理器中注冊監(jiān)聽器對象。

Criteria:該類使得應(yīng)用能夠通過在LocationProvider中設(shè)置的屬性來選擇合適的定位提供者。

Geocoder:用于處理地理編碼和反向地理編碼的類。地理編碼是指將地址或其他描述轉(zhuǎn)變?yōu)榻?jīng)度和緯度,反向地理編碼則是將經(jīng)度和緯度轉(zhuǎn)變?yōu)榈刂坊蛎枋稣Z言,其中包含了兩個(gè)構(gòu)造函數(shù),需要傳入經(jīng)度和緯度的坐標(biāo)。getFromLocation方法可以得到一組關(guān)于地址的數(shù)組。

下面開始地圖定位實(shí)例的開發(fā),在開發(fā)地圖前需要獲取Android地圖API密鑰網(wǎng)上有很多資料,這里就不再復(fù)述。

首先要在manifest.xml中設(shè)置全相應(yīng)的權(quán)限和maps庫:

[html]view plaincopy

android:icon="@drawable/ic_launcher"

android:label="@string/app_name">

android:label="@string/app_name"

android:name=".MyMapActivity">

在上面我標(biāo)紅的千萬不要忘記。

layout下的main.xml:

[html]view plaincopy


android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical">

android:id="@+id/mapview"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:apiKey="008uu0x2a7GWlK2LzCW872afBAPLhJ-U2R26Wgw"

/>

下面是核心代碼,重要的地方我做了注釋:

[html]view plaincopy

public?class?MyMapActivity?extends?MapActivity?{

/**?Called?when?the?activity?is?first?created.?*/

private?MapController?mapController;

private?MapView?mapView;

private?MyOverLay?myOverLay;

@Override

public?void?onCreate(Bundle?savedInstanceState)?{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

LocationManagerlocationManager=(LocationManager)?getSystemService(Context.LOCATION_SERVICE);

mapView=(MapView)?this.findViewById(R.id.mapview);

//設(shè)置交通模式

mapView.setTraffic(true);

//設(shè)置衛(wèi)星模式

mapView.setSatellite(false);

//設(shè)置街景模式

mapView.setStreetView(false);

//設(shè)置縮放控制

mapView.setBuiltInZoomControls(true);

mapView.setClickable(true);

mapView.setEnabled(true);

//得到MapController實(shí)例

mapController=mapView.getController();

mapController.setZoom(15);

myOverLay=newMyOverLay();

ListoverLays=mapView.getOverlays();

overLays.add(myOverLay);

Criteriacriteria=newCriteria();

criteria.setAccuracy(Criteria.ACCURACY_FINE);

criteria.setAltitudeRequired(false);

criteria.setBearingRequired(false);

criteria.setCostAllowed(false);

criteria.setPowerRequirement(Criteria.POWER_LOW);

//取得效果最好的Criteria

Stringprovider=locationManager.getBestProvider(criteria,?true);

//得到Location

Locationlocation=locationManager.getLastKnownLocation(provider);

updateWithLocation(location);

//注冊一個(gè)周期性的更新,3秒一次

locationManager.requestLocationUpdates(provider,?3000,?0,?locationListener);

}

@Override

public?boolean?onCreateOptionsMenu(Menu?menu)?{

//?TODO?Auto-generated?method?stub

menu.add(0,?1,?1,?"交通模式");

menu.add(0,2,2,"衛(wèi)星模式");

menu.add(0,3,3,"街景模式");

return?super.onCreateOptionsMenu(menu);

}

@Override

public?boolean?onOptionsItemSelected(MenuItem?item)?{

//?TODO?Auto-generated?method?stub

super.onOptionsItemSelected(item);

switch?(item.getItemId())?{

case?1://交通模式

mapView.setTraffic(true);

mapView.setSatellite(false);

mapView.setStreetView(false);

break;

case?2://衛(wèi)星模式

mapView.setSatellite(true);

mapView.setStreetView(false);

mapView.setTraffic(false);

break;

case?3://街景模式

mapView.setStreetView(true);

mapView.setTraffic(false);

mapView.setSatellite(false);

break;

default:

mapView.setTraffic(true);

mapView.setSatellite(false);

mapView.setStreetView(false);

break;

}

return?true;

}

private?void?updateWithLocation(Location?location){

if(location!=null){

//為繪制類設(shè)置坐標(biāo)

myOverLay.setLocation(location);

GeoPointgeoPoint=newGeoPoint((int)(location.getLatitude()*1E6),?(int)(location.getLongitude()*1E6));

//定位到指定的坐標(biāo)

mapController.animateTo(geoPoint);

mapController.setZoom(15);

}

}

private?final?LocationListenerlocationListener=newLocationListener()?{

@Override

public?void?onStatusChanged(String?provider,?int?status,?Bundle?extras)?{

//?TODO?Auto-generated?method?stub

}

@Override

public?void?onProviderEnabled(String?provider)?{

//?TODO?Auto-generated?method?stub

}

@Override

public?void?onProviderDisabled(String?provider)?{

//?TODO?Auto-generated?method?stub

}

//當(dāng)坐標(biāo)改變時(shí)出發(fā)此函數(shù)

@Override

public?void?onLocationChanged(Location?location)?{

//?TODO?Auto-generated?method?stub

updateWithLocation(location);

}

};

class?MyOverLay?extends?Overlay{

private?Location?location;

public?void?setLocation(Location?location){

this.location=location;

}

@Override

public?boolean?draw(Canvas?canvas,?MapView?mapView,?boolean?shadow,

long?when)?{

//?TODO?Auto-generated?method?stub

super.draw(canvas,?mapView,?shadow);

Paintpaint=newPaint();

PointmyScreen=newPoint();

//將經(jīng)緯度換成實(shí)際屏幕的坐標(biāo)。

GeoPointgeoPoint=newGeoPoint((int)(location.getLatitude()*1E6),?(int)(location.getLongitude()*1E6));

mapView.getProjection().toPixels(geoPoint,?myScreen);

paint.setStrokeWidth(1);

paint.setARGB(255,?255,?0,?0);

paint.setStyle(Paint.Style.STROKE);

Bitmapbmp=BitmapFactory.decodeResource(getResources(),?R.drawable.mypicture);

//把這張圖片畫到相應(yīng)的位置。

canvas.drawBitmap(bmp,?myScreen.x,?myScreen.y,paint);

canvas.drawText("天堂沒有路",?myScreen.x,?myScreen.y,?paint);

return?true;

}

}

@Override

protected?boolean?isRouteDisplayed()?{

//?TODO?Auto-generated?method?stub

return?false;

}

@Override

public?boolean?onKeyDown(int?keyCode,?KeyEvent?event)?{

//?TODO?Auto-generated?method?stub

if?(keyCode==?KeyEvent.KEYCODE_BACK)?{

AlertDialog.Builderbuilder=newAlertDialog.Builder(this);

builder.setMessage("你確定退出嗎?")

.setCancelable(false)

.setPositiveButton("確定",

new?DialogInterface.OnClickListener()?{

public?void?onClick(DialogInterface?dialog,

int?id)?{

MyMapActivity.this.finish();

android.os.Process

.killProcess(android.os.Process

.myPid());

android.os.Process.killProcess(android.os.Process.myTid());

android.os.Process.killProcess(android.os.Process.myUid());

}

})

.setNegativeButton("返回",

new?DialogInterface.OnClickListener()?{

public?void?onClick(DialogInterface?dialog,

int?id)?{

dialog.cancel();

}

});

AlertDialogalert=builder.create();

alert.show();

return?true;

}

return?super.onKeyDown(keyCode,?event);

}

}

接下來看一下運(yùn)行后效果:

可以放大縮?。?/p>

可是使用menu鍵,切換不同的模式:

上面是切換到了衛(wèi)星模式。由于地圖需要耗費(fèi)大量的網(wǎng)絡(luò)資源,如果網(wǎng)絡(luò)比較慢的話會等待很長時(shí)間。

歡迎加技術(shù)學(xué)習(xí)交流群:364595326

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容