利用百度地圖Android sdk高仿微信發送位置功能


接觸了百度地圖開發平台半個月了,這2天試着模仿了微信給好友發送位置功能,對百度地圖的操作能力又上了一個台階

假設須要完整demo。請評論留下郵箱

(眼下源代碼已經不發送,假設須要源代碼。加qq316701116,不喜勿擾)

 

 我在實現這個功能的時候,遇到一些困難,可能也是別人將會遇到的困難,特在此列出


1、在微信發送功能中,無論用戶怎樣拖拽地圖。總有個覆蓋物固定了MapView中央,怎么實現?

    事實上這非常easy實現。僅僅要MapView的布局文件里。將一個ImageView覆蓋在MapView的中央,就行實現無論用戶怎樣拖拽地圖。覆蓋物(ImageView)總固定總MapView中央


2、怎樣獲取MapView中央的地理坐標。也即是屏幕覆蓋物處的坐標?

    要獲取MapView中央的地理坐標,首先先獲取覆蓋物在屏幕上的物理坐標。這里得差別一下地理坐標(經緯度)和物理坐標(xy軸);

   能夠通過

[java]  view plain copy
  1. <mCenterPoint = mBaiduMap.getMapStatus().targetScreen;//mBaiduMap是BaiduMap類的實例  
來獲取物理坐標,這個物理坐標是不變的,而物理坐標相應的地理坐標卻是隨着用戶拖拽地圖而改變。所以。當我們須要地理坐標時,能夠通過

[java]  view plain copy
  1. currentLatLng = mBaiduMap.getProjection().fromScreenLocation(  
  2.                         mCenterPoint); 
獲取。


3、怎樣獲取該地理坐標周圍的全部poi信息(也就是周圍建築物的信息),而不僅僅是某個類型的興趣點?

為了實現這個功能,真是費了我好大勁,由於我之前一直以為用POI周邊搜索實現的,有人提示我能夠通過循環軸線搜索實現不同keyword搜索,但這樣子確實非常難實現跟微信那樣的效果。通過查看API,發現能夠通過反地理編碼解決問題,至於什么事反地理編碼,能夠到百度地圖官網了解,通過調用它。能夠返回一個該地理坐標附近建築信息的一個列表


4、當用戶拖拽地圖,怎樣讓列表更新到眼下中心地理位置的周邊信息?

這個困難事實上也不難實現。僅僅是重寫mBaiduMap.setOnMapTouchListener(touchListener);觸摸事件,在觸摸監聽器的回調函數中

將MapView中央的物理坐標轉換成相應的地理坐標,再通過反地理編碼獲取周邊信息。道理同問題3


5、當點擊listview某一項時。怎樣將項地理位置顯示在MapView也就是屏幕中央?

非常easy,通過listview的適配器獲取item的位置信息,包含經緯度。然后用動畫跳轉到屏幕中央位置就可以。


我覺得上面5個問題是實現這個功能的關鍵所在,以下是效果圖(假設須要完整demo,請評論留下郵箱


上面是一個MapVIew。覆蓋物固定在當中央,地圖左下角的白色正方形是回到定位點的button。由於沒找到好看的圖片,就留着空白了

以下是一個listView。顯示地圖指示地點周圍的一些位置信息


貼一下實現該功能的核心代碼

Activity類

[java]  view plain copy
  1. package com.vr.souhuodong.UI.Sou;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.Intent;  
  8. import android.graphics.Point;  
  9. import android.net.Uri;  
  10. import android.os.Bundle;  
  11. import android.view.MotionEvent;  
  12. import android.view.View;  
  13. import android.widget.AdapterView;  
  14. import android.widget.AdapterView.OnItemClickListener;  
  15. import android.widget.ImageView;  
  16. import android.widget.ListView;  
  17. import android.widget.ProgressBar;  
  18.   
  19. import com.baidu.location.BDLocation;  
  20. import com.baidu.location.BDLocationListener;  
  21. import com.baidu.location.LocationClient;  
  22. import com.baidu.location.LocationClientOption;  
  23. import com.baidu.mapapi.map.BaiduMap;  
  24. import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener;  
  25. import com.baidu.mapapi.map.BitmapDescriptor;  
  26. import com.baidu.mapapi.map.BitmapDescriptorFactory;  
  27. import com.baidu.mapapi.map.MapStatusUpdate;  
  28. import com.baidu.mapapi.map.MapStatusUpdateFactory;  
  29. import com.baidu.mapapi.map.MapView;  
  30. import com.baidu.mapapi.map.MarkerOptions;  
  31. import com.baidu.mapapi.map.MyLocationConfiguration;  
  32. import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;  
  33. import com.baidu.mapapi.map.MyLocationData;  
  34. import com.baidu.mapapi.map.OverlayOptions;  
  35. import com.baidu.mapapi.model.LatLng;  
  36. import com.baidu.mapapi.search.core.PoiInfo;  
  37. import com.baidu.mapapi.search.core.SearchResult;  
  38. import com.baidu.mapapi.search.geocode.GeoCodeResult;  
  39. import com.baidu.mapapi.search.geocode.GeoCoder;  
  40. import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;  
  41. import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;  
  42. import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;  
  43. import com.vr.souhuodong.R;  
  44. import com.vr.souhuodong.UI.Adapter.PlaceListAdapter;  
  45.   
  46. public class ChoosePlaceActivity extends Activity {  
  47.   
  48.     MapView mMapView;  
  49.     BaiduMap mBaiduMap;  
  50.     ProgressBar mLoadBar;  
  51.     ImageView mSelectImg;  
  52.   
  53.     // 定位  
  54.     LocationClient mLocationClient = null;  
  55.     MyBDLocationListner mListner = null;  
  56.     BitmapDescriptor mCurrentMarker = null;  
  57.   
  58.     // 當前經緯度  
  59.     double mLantitude;  
  60.     double mLongtitude;  
  61.     LatLng mLoactionLatLng;  
  62.   
  63.     // 設置第一次定位標志  
  64.     boolean isFirstLoc = true;  
  65.   
  66.     // MapView中央對於的屏幕坐標  
  67.     Point mCenterPoint = null;  
  68.   
  69.     // 地理編碼  
  70.     GeoCoder mGeoCoder = null;  
  71.   
  72.     // 位置列表  
  73.     ListView mListView;  
  74.     PlaceListAdapter mAdapter;  
  75.     List<PoiInfo> mInfoList;  
  76.     PoiInfo mCurentInfo;  
  77.   
  78.     @Override  
  79.     protected void onCreate(Bundle savedInstanceState) {  
  80.         // TODO Auto-generated method stub  
  81.         super.onCreate(savedInstanceState);  
  82.         setContentView(R.layout.activity_chooseplace);  
  83.   
  84.         initView();  
  85.     }  
  86.   
  87.     /** 
  88.      * 初始化界面 
  89.      */  
  90.     private void initView() {  
  91.         // TODO Auto-generated method stub  
  92.         // 初始化地圖  
  93.         mMapView = (MapView) findViewById(R.id.chooseplace_bmapView);  
  94.         mMapView.showZoomControls(false);  
  95.         mBaiduMap = mMapView.getMap();  
  96.         MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);  
  97.         mBaiduMap.setMapStatus(msu);  
  98.         mBaiduMap.setOnMapTouchListener(touchListener);  
  99.   
  100.         // 初始化POI信息列表  
  101.         mInfoList = new ArrayList<PoiInfo>();  
  102.   
  103.         // 初始化當前MapView中心屏幕坐標,初始化當前地理坐標  
  104.         mCenterPoint = mBaiduMap.getMapStatus().targetScreen;  
  105.         mLoactionLatLng = mBaiduMap.getMapStatus().target;  
  106.   
  107.         // 定位  
  108.         mBaiduMap.setMyLocationEnabled(true);  
  109.         mLocationClient = new LocationClient(this);  
  110.         mListner = new MyBDLocationListner();  
  111.         mLocationClient.registerLocationListener(mListner);  
  112.         LocationClientOption option = new LocationClientOption();  
  113.         option.setOpenGps(true);// 打開gps  
  114.         option.setCoorType("bd09ll"); // 設置坐標類型  
  115.         option.setScanSpan(1000);  
  116.         mLocationClient.setLocOption(option);  
  117.         mLocationClient.start();  
  118.   
  119.         // 地理編碼  
  120.         mGeoCoder = GeoCoder.newInstance();  
  121.         mGeoCoder.setOnGetGeoCodeResultListener(GeoListener);  
  122.   
  123.         // 周邊位置列表  
  124.         mListView = (ListView) findViewById(R.id.place_list);  
  125.         mLoadBar = (ProgressBar) findViewById(R.id.place_progressBar);  
  126.         mListView.setOnItemClickListener(itemClickListener);  
  127.         mAdapter = new PlaceListAdapter(getLayoutInflater(), mInfoList);  
  128.         mListView.setAdapter(mAdapter);  
  129.   
  130.         mSelectImg = new ImageView(this);  
  131.     }  
  132.   
  133.     public void turnBack(View view) {  
  134.         // 實現動畫跳轉  
  135.         MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);  
  136.         mBaiduMap.animateMapStatus(u);  
  137.   
  138.         mBaiduMap.clear();  
  139.         // 發起反地理編碼檢索  
  140.         mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())  
  141.                 .location(mLoactionLatLng));  
  142.   
  143.     }  
  144.   
  145.     @Override  
  146.     protected void onDestroy() {  
  147.         // TODO Auto-generated method stub  
  148.         super.onDestroy();  
  149.         mLocationClient.stop();  
  150.         mGeoCoder.destroy();  
  151.     }  
  152.   
  153.     // 定位監聽器  
  154.     private class MyBDLocationListner implements BDLocationListener {  
  155.   
  156.         @Override  
  157.         public void onReceiveLocation(BDLocation location) {  
  158.             // TODO Auto-generated method stub  
  159.             // map view 銷毀后不在處理新接收的位置  
  160.             if (location == null || mMapView == null)  
  161.                 return;  
  162.             MyLocationData data = new MyLocationData.Builder()//  
  163.                     // .direction(mCurrentX)//  
  164.                     .accuracy(location.getRadius())//  
  165.                     .latitude(location.getLatitude())//  
  166.                     .longitude(location.getLongitude())//  
  167.                     .build();  
  168.             mBaiduMap.setMyLocationData(data);  
  169.             // 設置自己定義圖標  
  170.             MyLocationConfiguration config = new MyLocationConfiguration(  
  171.                     LocationMode.NORMAL, truenull);  
  172.             mBaiduMap.setMyLocationConfigeration(config);  
  173.   
  174.             mLantitude = location.getLatitude();  
  175.             mLongtitude = location.getLongitude();  
  176.   
  177.             LatLng currentLatLng = new LatLng(mLantitude, mLongtitude);  
  178.             mLoactionLatLng = new LatLng(mLantitude, mLongtitude);  
  179.   
  180.             // 是否第一次定位  
  181.             if (isFirstLoc) {  
  182.                 isFirstLoc = false;  
  183.                 // 實現動畫跳轉  
  184.                 MapStatusUpdate u = MapStatusUpdateFactory  
  185.                         .newLatLng(currentLatLng);  
  186.                 mBaiduMap.animateMapStatus(u);  
  187.   
  188.                 mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())  
  189.                         .location(currentLatLng));  
  190.                 return;  
  191.             }  
  192.   
  193.         }  
  194.   
  195.     }  
  196.   
  197.     // 地理編碼監聽器  
  198.     OnGetGeoCoderResultListener GeoListener = new OnGetGeoCoderResultListener() {  
  199.         public void onGetGeoCodeResult(GeoCodeResult result) {  
  200.             if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {  
  201.                 // 沒有檢索到結果  
  202.             }  
  203.             // 獲取地理編碼結果  
  204.         }  
  205.   
  206.         @Override  
  207.         public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {  
  208.             if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {  
  209.                 // 沒有找到檢索結果  
  210.             }  
  211.             // 獲取反向地理編碼結果  
  212.             else {  
  213.                 // 當前位置信息  
  214.                 mCurentInfo = new PoiInfo();  
  215.                 mCurentInfo.address = result.getAddress();  
  216.                 mCurentInfo.location = result.getLocation();  
  217.                 mCurentInfo.name = "[位置]";  
  218.                 mInfoList.clear();  
  219.                 mInfoList.add(mCurentInfo);  
  220.   
  221.                 // 將周邊信息增加表  
  222.                 if (result.getPoiList() != null) {  
  223.                     mInfoList.addAll(result.getPoiList());  
  224.                 }  
  225.                 // 通知適配數據已改變  
  226.                 mAdapter.notifyDataSetChanged();  
  227.                 mLoadBar.setVisibility(View.GONE);  
  228.   
  229.             }  
  230.         }  
  231.     };  
  232.   
  233.     // 地圖觸摸事件監聽器  
  234.     OnMapTouchListener touchListener = new OnMapTouchListener() {  
  235.         @Override  
  236.         public void onTouch(MotionEvent event) {  
  237.             // TODO Auto-generated method stub  
  238.             if (event.getAction() == MotionEvent.ACTION_UP) {  
  239.   
  240.                 if (mCenterPoint == null) {  
  241.                     return;  
  242.                 }  
  243.   
  244.                 // 獲取當前MapView中心屏幕坐標相應的地理坐標  
  245.                 LatLng currentLatLng;  
  246.                 currentLatLng = mBaiduMap.getProjection().fromScreenLocation(  
  247.                         mCenterPoint);  
  248.                 System.out.println("----" + mCenterPoint.x);  
  249.                 System.out.println("----" + currentLatLng.latitude);  
  250.                 // 發起反地理編碼檢索  
  251.                 mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())  
  252.                         .location(currentLatLng));  
  253.                 mLoadBar.setVisibility(View.VISIBLE);  
  254.   
  255.             }  
  256.         }  
  257.     };  
  258.   
  259.     // listView選項點擊事件監聽器  
  260.     OnItemClickListener itemClickListener = new OnItemClickListener() {  
  261.   
  262.         @Override  
  263.         public void onItemClick(AdapterView<?

    > parent, View view, int position,  

  264.                 long id) {  
  265.             // TODO Auto-generated method stub  
  266.   
  267.             // 通知是適配器第position個item被選擇了  
  268.             mAdapter.setNotifyTip(position);  
  269.   
  270.             BitmapDescriptor mSelectIco = BitmapDescriptorFactory  
  271.                     .fromResource(R.drawable.icon_geo);  
  272.             mBaiduMap.clear();  
  273.             PoiInfo info = (PoiInfo) mAdapter.getItem(position);  
  274.             LatLng la = info.location;  
  275.   
  276.             // 動畫跳轉  
  277.             MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(la);  
  278.             mBaiduMap.animateMapStatus(u);  
  279.   
  280.             // 加入覆蓋物  
  281.             OverlayOptions ooA = new MarkerOptions().position(la)  
  282.                     .icon(mSelectIco).anchor(0.5f, 0.5f);  
  283.             mBaiduMap.addOverlay(ooA);  
  284.   
  285.             // 選中項打勾  
  286.             mSelectImg.setBackgroundResource(R.drawable.greywhite);  
  287.             mSelectImg = (ImageView) view.findViewById(R.id.place_select);  
  288.             mSelectImg.setBackgroundResource(R.drawable.ic_select);  
  289.               
  290. //          Uri mUri = Uri.parse("geo:39.940409,116.355257");  
  291. //          Intent mIntent = new Intent(Intent.ACTION_VIEW,mUri);  
  292. //          startActivity(mIntent);  
  293.   
  294.         }  
  295.   
  296.     };  
  297. }  


自己定義的listView適配器

[java]  view plain copy
  1. package com.vr.souhuodong.UI.Adapter;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.R.integer;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.view.ViewGroup;  
  10. import android.widget.BaseAdapter;  
  11. import android.widget.ImageView;  
  12. import android.widget.TextView;  
  13.   
  14. import com.baidu.mapapi.search.core.PoiInfo;  
  15. import com.vr.souhuodong.R;  
  16.   
  17. public class PlaceListAdapter extends BaseAdapter {  
  18.       
  19.     List<PoiInfo> mList;  
  20.     LayoutInflater mInflater;  
  21.     int notifyTip ;  
  22.       
  23.     private class MyViewHolder {  
  24.         TextView placeName;  
  25.         TextView placeAddree;  
  26.         ImageView placeSelected;  
  27.     }  
  28.   
  29.     public PlaceListAdapter(LayoutInflater mInflater , List<PoiInfo> mList) {  
  30.         super();  
  31.         this.mList = mList;  
  32.         this.mInflater = mInflater;  
  33.         notifyTip = -1 ;  
  34.     }  
  35.       
  36.       
  37.     /** 
  38.      * 設置第幾個item被選擇 
  39.      * @param notifyTip 
  40.      */  
  41.     public void setNotifyTip(int notifyTip) {  
  42.         this.notifyTip = notifyTip;  
  43.     }  
  44.       
  45.     @Override  
  46.     public int getCount() {  
  47.         // TODO Auto-generated method stub  
  48.         return mList.size();  
  49.     }  
  50.   
  51.     @Override  
  52.     public Object getItem(int position) {  
  53.         // TODO Auto-generated method stub  
  54.         return mList.get(position);  
  55.     }  
  56.   
  57.     @Override  
  58.     public long getItemId(int position) {  
  59.         // TODO Auto-generated method stub  
  60.         return position;  
  61.     }  
  62.   
  63.     @Override  
  64.     public View getView(int position, View convertView, ViewGroup parent) {  
  65.         // TODO Auto-generated method stub  
  66.         MyViewHolder holder;  
  67.         if (convertView == null) {  
  68.             System.out.println("----aa-");  
  69.             convertView = mInflater.inflate(com.vr.souhuodong.R.layout.listitem_place, parent, false);        
  70.             holder = new MyViewHolder();  
  71.             holder.placeName = (TextView) convertView  
  72.                     .findViewById(com.vr.souhuodong.R.id.place_name);  
  73.             holder.placeAddree = (TextView) convertView  
  74.                     .findViewById(com.vr.souhuodong.R.id.place_adress);  
  75.             holder.placeSelected = (ImageView) convertView  
  76.                     .findViewById(com.vr.souhuodong.R.id.place_select);  
  77.             holder.placeName.setText(mList.get(position).name);  
  78.             holder.placeAddree.setText(mList.get(position).address);  
  79.             holder.placeSelected.setBackgroundResource(R.drawable.greywhite);  
  80.             convertView.setTag(holder);  
  81.         } else {  
  82.             holder = (MyViewHolder) convertView.getTag();             
  83.         }  
  84.         holder.placeName.setText(mList.get(position).name);  
  85.         holder.placeAddree.setText(mList.get(position).address);  
  86.         //依據又一次載入的時候第position條item是否是當前所選擇的,選擇載入不同的圖片  
  87.         if(notifyTip == position ){           
  88.             holder.placeSelected.setBackgroundResource(R.drawable.ic_select);  
  89.         }             
  90.         else {  
  91.             holder.placeSelected.setBackgroundResource(R.drawable.greywhite);  
  92.         }  
  93.   
  94.         return convertView;  
  95.     }  
  96.       
  97.       
  98. //  class MyItemClickListener implements OnClickListener {  
  99. //  
  100. //      ImageView mImg;  
  101. //      public MyItemClickListener(ImageView mImg) {  
  102. //          this.mImg = mImg;   
  103. //      }  
  104. //      @Override  
  105. //      public void onClick(View v) {  
  106. //          // TODO Auto-generated method stub  
  107. //          mImg.setBackgroundResource(R.drawable.ic_select);  
  108. //      }  
  109. //        
  110. //  }  
  111.       
  112.   



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM