近因爲項目須要,研究了下百度地圖定位,他們提供的實例基本都是用監聽器實現自動定位的。我想實現一種效果:當用戶進入UI時,不定位,用戶須要定位的時候,本身手動點擊按鈕,再去定位當前位置。 通過2天研究和諮詢,找到了解決方案,在此備忘一下。
注意:定位使用真機纔可以真正定位;模擬器的話,在DDMS中的Emulator Control中,選擇Manual,下面單選按鈕選擇Decimal,而後填寫經緯度,send後,再點擊定位個人位置按鈕,就能定位了(這應該算是固定定位,哈哈。。。)、 android
一、第一步固然是獲取一個針對本身項目的key值。http://dev.baidu.com/wiki/static/imap/key/ git
二、使用百度API是有前提的,摘自百度:首先將API包括的兩個文件baidumapapi.jar和libBMapApiEngine.so拷貝到工程根目錄及libs\armeabi目錄下,並在工程屬性->Java Build Path->Libraries中選擇「Add JARs」,選定baidumapapi.jar,肯定後返回,這樣您就能夠在您的程序中使用API了。(這兩個文件見附件)。 api
三、按照本身的需求寫一個layout,個人以下: 緩存
<?xml version="1.0" encoding="utf-8"?> 網絡
Xml代碼
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
-
- <TextView
- android:id="@+id/myLocation_id"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textSize="15dp"
- android:gravity="center_horizontal"
- android:textColor="@drawable/black"
- android:background="@drawable/gary"
- />
-
- <com.baidu.mapapi.MapView android:id="@+id/bmapsView"
- android:layout_width="fill_parent" android:layout_height="fill_parent"
- android:clickable="true" android:layout_weight="1"
- />
-
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/location_button_id"
- android:text="@string/location_button_text"
- />
-
- </LinearLayout>
須要特別注意的是:<com.baidu.mapapi.MapView /> 這玩意。 app
四、寫一個MapApplication實現application,提供全局的BMapManager,以及其初始化。 異步
Java代碼
- public BMapManager mapManager = null;
- static MapApplication app;
- public String mStrKey = "你申請的key值";
-
- @Override
- public void onCreate() {
- mapManager = new BMapManager(this);
- mapManager.init(mStrKey, new MyGeneralListener());
- }
- @Override
- //建議在您app的退出以前調用mapadpi的destroy()函數,避免重複初始化帶來的時間消耗
- public void onTerminate() {
- // TODO Auto-generated method stub
- if(mapManager != null)
- {
- mapManager.destroy();
- mapManager = null;
- }
- super.onTerminate();
- }
-
- static class MyGeneralListener implements MKGeneralListener{
-
- @Override
- public void onGetNetworkState(int arg0) {
- Toast.makeText(MapApplication.app.getApplicationContext(), "您的網絡出錯啦!",
- Toast.LENGTH_LONG).show();
- }
- @Override
- public void onGetPermissionState(int iError) {
- if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
- // 受權Key錯誤:
- Toast.makeText(MapApplication.app.getApplicationContext(),"您的受權Key不正確!",
- Toast.LENGTH_LONG).show();
- }
- }
- }
- 5、接下來就是按照百度api寫定位代碼了,使用handler機制去添加定位圖層,須要說明的都在註釋上了。
-
- private BMapManager mBMapMan = null;
- private MapView mMapView = null;
- private MapController bMapController;
- private MKLocationManager mkLocationManager;
- private MKSearch mkSearch;
-
- private TextView address_view; //定位到的位置信息
-
- private ProgressDialog dialog;
- private List<HotelInfo> hotelList;
-
- private int distance = 1000; //查詢的範圍(單位:m)
-
- Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
-
- double lat = msg.getData().getDouble("lat");
- double lon = msg.getData().getDouble("lon");
- if(lat!=0&&lon!=0){
- GeoPoint point = new GeoPoint(
- (int) (lat * 1E6),
- (int) (lon * 1E6));
- bMapController.animateTo(point); //設置地圖中心點
- bMapController.setZoom(15);
-
- mkSearch.reverseGeocode(point); //解析地址(異步方法)
-
- MyLocationOverlay myLoc = new MyLocationOverlayFromMap(ShowMapAct.this,mMapView);
- myLoc.enableMyLocation(); // 啓用定位
- myLoc.enableCompass(); // 啓用指南針
- mMapView.getOverlays().add(myLoc);
- }else{
- Toast.makeText(ShowMapAct.this, "沒有加載到您的位置", Toast.LENGTH_LONG).show();
- }
-
- if(hotelList!=null){
- Drawable marker = getResources().getDrawable(R.drawable.iconmarka); //設置marker
- marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight()); //爲maker定義位置和邊界
- mMapView.getOverlays().add(new OverItemList(marker,hotelList,ShowMapAct.this,bMapController));
- }else if(hotelList==null&&lat!=0&&lon!=0){
- Toast.makeText(ShowMapAct.this, "網絡異常,沒有獲取到酒店信息。", Toast.LENGTH_LONG).show();
- }
- if(dialog!=null) dialog.dismiss();
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
-
- distance = getIntent().getExtras().getInt("distance"); //獲取查詢範圍
-
- super.onCreate(savedInstanceState);
- setContentView(R.layout.location);
-
- mMapView = (MapView)findViewById(R.id.bmapsView); //初始化一個mapView 存放Map
- init(); //初始化地圖管理器
- super.initMapActivity(mBMapMan);
-
-
- address_view = (TextView)findViewById(R.id.myLocation_id);
- SpannableStringBuilder style = new SpannableStringBuilder(String.format(getResources().getString(R.string.location_text),"位置不詳"));
- style.setSpan(new ForegroundColorSpan(Color.RED), 5, style.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- address_view.setText(style);
-
- Button location_button = (Button)findViewById(R.id.location_button_id);
- location_button.setOnClickListener(new View.OnClickListener(){
- @Override
- public void onClick(View v) {
- dialog = ProgressDialog.show(ShowMapAct.this, "", "數據加載中,請稍後.....");
- new Thread(new MyThread()).start();
- }
- });
-
- mkSearch = new MKSearch(); //初始化一個MKSearch,根據location解析詳細地址
- mkSearch.init(mBMapMan, this);
- mMapView.setBuiltInZoomControls(true); //啓用內置的縮放控件
- bMapController = mMapView.getController();
- GeoPoint defaultPoint = new GeoPoint((int) (39.920934 * 1E6),(int) (116.412817 * 1E6)); //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6)
- bMapController.setCenter(defaultPoint); //設置地圖中心點
- bMapController.setZoom(12); //設置地圖zoom級別
-
- mkLocationManager = mBMapMan.getLocationManager();
- }
- /**
- * 初始化地圖管理器BMapManager
- */
- public void init(){
- MapApplication app = (MapApplication)getApplication();
- if (app.mapManager == null) {
- app.mapManager = new BMapManager(getApplication());
- app.mapManager.init(app.mStrKey, new MapApplication.MyGeneralListener());
- }
- mBMapMan = app.mapManager;
- }
-
- @Override
- protected void onDestroy() {
- MapApplication app = (MapApplication)getApplication();
- if (mBMapMan != null) {
- mBMapMan.destroy();
- app.mapManager.destroy();
- app.mapManager = null;
- mBMapMan = null;
- }
- super.onDestroy();
- }
-
-
- @Override
- protected void onPause() {
- if (mBMapMan != null) {
- // 終止百度地圖API
- mBMapMan.stop();
- }
- super.onPause();
- }
-
- @Override
- protected void onResume() {
- if (mBMapMan != null) {
- // 開啓百度地圖API
- mBMapMan.start();
- }
- super.onResume();
- }
-
- @Override
- protected boolean isRouteDisplayed() {
- return false;
- }
-
- @Override
- public void onGetAddrResult(MKAddrInfo result, int iError) {
- if(result==null) return;
- SpannableStringBuilder style = new SpannableStringBuilder(String.format(getResources().getString(R.string.location_text),result.strAddr));
- style.setSpan(new ForegroundColorSpan(Color.RED), 5, style.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- address_view.setText(style);
- if(dialog!=null) dialog.dismiss();
- }
-
- @Override
- public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {}
- @Override
- public void onGetPoiResult(MKPoiResult arg0, int arg1, int arg2) {}
- @Override
- public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {}
- @Override
- public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {}
-
- /**
- * 從新定位,加載數據
- * @author Administrator
- *
- */
- class MyThread implements Runnable{
- @Override
- public void run() {
- /**
- * 最重要的就是這個玩意
- * 因爲LocationListener獲取第一個位置修正的時間會很長,爲了不用戶等待,
- * 在LocationListener獲取第一個更精確的位置以前,應當使用getLocationInfo() 獲取一個緩存的位置
- */
- Location location = mkLocationManager.getLocationInfo();
- double lat = 0d,lon = 0d;
- if(location!=null){ //定位到位置
- String coordinate = location.getLatitude()+","+location.getLongitude();
- HotelRemoteData hotelData = new HotelRemoteData();
- /**
- * 遠程獲取酒店列表數據
- */
- hotelList = hotelData.getHotelToMap(coordinate,distance);
- lat = location.getLatitude();
- lon = location.getLongitude();
- }
-
- Message msg = new Message();
- Bundle data = new Bundle();
- data.putDouble("lat", lat);
- data.putDouble("lon", lon);
- msg.setData(data);
- handler.sendMessage(msg);
- }
- }
六、還有一種就是百度示例至關推薦的,也是加載定位位置速度比較快的,那就是經過定位監聽器來定位信息。沒啥難的,照着百度的示例寫,都能搞定。 ide
Java代碼
- LocationListener listener = new LocationListener() {
- @Override
- /** 位置變化,百度地圖即會調用該方法去獲取位置信息。
- * (我測試發現就算手機不動,它也會偶爾從新去加載位置;只要你經過重力感應,他就必定會從新加載)
- */
- public void onLocationChanged(Location location) {
- GeoPoint gp = new GeoPoint((int) (location.getLatitude() * 1E6), (int) (location.getLongitude() * 1E6)); //經過地圖上的經緯度轉換爲地圖上的座標點
- bMapController.animateTo(gp); //動畫般的移動到定位的位置
- }
- };