利用百度地圖Android sdk高仿微信發(fā)送位置功能及遇到的問題
接觸了百度地圖開發(fā)平臺(tái)半個(gè)月了,這2天試著模仿了微信給好友發(fā)送位置功能,對(duì)百度地圖的操作能力又上了一個(gè)臺(tái)階
我在實(shí)現(xiàn)這個(gè)功能的時(shí)候,遇到一些困難,可能也是別人將會(huì)遇到的困難,特在此列出
1、在微信發(fā)送功能中,不管用戶如何拖拽地圖,總有個(gè)覆蓋物固定了MapView中央,怎么實(shí)現(xiàn)?
其實(shí)這很容易實(shí)現(xiàn),只要MapView的布局文件中,將一個(gè)ImageView覆蓋在MapView的中央,就能夠?qū)崿F(xiàn)不管用戶如何拖拽地圖,覆蓋物(ImageView)總固定總MapView中央
2、如何獲取MapView中央的地理坐標(biāo),也即是屏幕覆蓋物處的坐標(biāo)?
要獲取MapView中央的地理坐標(biāo),首先先獲取覆蓋物在屏幕上的物理坐標(biāo),這里得區(qū)別一下地理坐標(biāo)(經(jīng)緯度)和物理坐標(biāo)(xy軸);
可以通過
<mCenterPoint = mBaiduMap.getMapStatus().targetScreen;//mBaiduMap是BaiduMap類的實(shí)例
來獲取物理坐標(biāo),這個(gè)物理坐標(biāo)是不變的,而物理坐標(biāo)對(duì)應(yīng)的地理坐標(biāo)卻是隨著用戶拖拽地圖而改變,所以,當(dāng)我們需要地理坐標(biāo)時(shí),可以通過
currentLatLng = mBaiduMap.getProjection().fromScreenLocation(
mCenterPoint);</strong></span>
獲取。
3、如何獲取該地理坐標(biāo)周圍的所有poi信息(也就是周圍建筑物的信息),而不只是某個(gè)類型的興趣點(diǎn)?
為了實(shí)現(xiàn)這個(gè)功能,真是費(fèi)了我好大勁,因?yàn)槲抑耙恢币詾橛茫校希芍苓吽阉鲗?shí)現(xiàn)的,有人提示我可以通過循環(huán)軸線搜索實(shí)現(xiàn)不同關(guān)鍵字搜索,但這樣子確實(shí)很難實(shí)現(xiàn)跟微信那樣的效果。通過查看API,發(fā)現(xiàn)可以通過反地理編碼解決這個(gè)問題,至于什么事反地理編碼,可以到百度地圖官網(wǎng)了解,通過調(diào)用它,可以返回一個(gè)該地理坐標(biāo)附近建筑信息的一個(gè)列表
4、當(dāng)用戶拖拽地圖,如何讓列表更新到目前中心地理位置的周邊信息?
這個(gè)困難其實(shí)也不難實(shí)現(xiàn),只是重寫mBaiduMap.setOnMapTouchListener(touchListener);觸摸事件,在觸摸監(jiān)聽器的回調(diào)函數(shù)中
將MapView中央的物理坐標(biāo)轉(zhuǎn)換成對(duì)應(yīng)的地理坐標(biāo),再通過反地理編碼獲取周邊信息,道理同問題3
5、當(dāng)點(diǎn)擊listview某一項(xiàng)時(shí),如何將項(xiàng)地理位置顯示在MapView也就是屏幕中央?
很簡(jiǎn)單,通過listview的適配器獲取item的位置信息,包括經(jīng)緯度,然后用動(dòng)畫跳轉(zhuǎn)到屏幕中央位置即可。
我認(rèn)為上面5個(gè)問題是實(shí)現(xiàn)這個(gè)功能的關(guān)鍵所在,下面是效果圖

上面是一個(gè)MapVIew,覆蓋物固定在其中央,地圖左下角的白色正方形是回到定位點(diǎn)的按鈕,因?yàn)闆]找到好看的圖片,就留著空白了
下面是一個(gè)listView,顯示地圖指示地點(diǎn)周圍的一些位置信息
貼一下實(shí)現(xiàn)該功能的核心代碼
Activity類
package com.vr.souhuodong.UI.Sou;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.vr.souhuodong.R;
import com.vr.souhuodong.UI.Adapter.PlaceListAdapter;
public class ChoosePlaceActivity extends Activity {
MapView mMapView;
BaiduMap mBaiduMap;
ProgressBar mLoadBar;
ImageView mSelectImg;
// 定位
LocationClient mLocationClient = null;
MyBDLocationListner mListner = null;
BitmapDescriptor mCurrentMarker = null;
// 當(dāng)前經(jīng)緯度
double mLantitude;
double mLongtitude;
LatLng mLoactionLatLng;
// 設(shè)置第一次定位標(biāo)志
boolean isFirstLoc = true;
// MapView中央對(duì)于的屏幕坐標(biāo)
Point mCenterPoint = null;
// 地理編碼
GeoCoder mGeoCoder = null;
// 位置列表
ListView mListView;
PlaceListAdapter mAdapter;
List<PoiInfo> mInfoList;
PoiInfo mCurentInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chooseplace);
initView();
}
/**
* 初始化界面
*/
private void initView() {
// TODO Auto-generated method stub
// 初始化地圖
mMapView = (MapView) findViewById(R.id.chooseplace_bmapView);
mMapView.showZoomControls(false);
mBaiduMap = mMapView.getMap();
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);
mBaiduMap.setMapStatus(msu);
mBaiduMap.setOnMapTouchListener(touchListener);
// 初始化POI信息列表
mInfoList = new ArrayList<PoiInfo>();
// 初始化當(dāng)前MapView中心屏幕坐標(biāo),初始化當(dāng)前地理坐標(biāo)
mCenterPoint = mBaiduMap.getMapStatus().targetScreen;
mLoactionLatLng = mBaiduMap.getMapStatus().target;
// 定位
mBaiduMap.setMyLocationEnabled(true);
mLocationClient = new LocationClient(this);
mListner = new MyBDLocationListner();
mLocationClient.registerLocationListener(mListner);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);// 打開gps
option.setCoorType("bd09ll"); // 設(shè)置坐標(biāo)類型
option.setScanSpan(1000);
mLocationClient.setLocOption(option);
mLocationClient.start();
// 地理編碼
mGeoCoder = GeoCoder.newInstance();
mGeoCoder.setOnGetGeoCodeResultListener(GeoListener);
// 周邊位置列表
mListView = (ListView) findViewById(R.id.place_list);
mLoadBar = (ProgressBar) findViewById(R.id.place_progressBar);
mListView.setOnItemClickListener(itemClickListener);
mAdapter = new PlaceListAdapter(getLayoutInflater(), mInfoList);
mListView.setAdapter(mAdapter);
mSelectImg = new ImageView(this);
}
public void turnBack(View view) {
// 實(shí)現(xiàn)動(dòng)畫跳轉(zhuǎn)
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);
mBaiduMap.animateMapStatus(u);
mBaiduMap.clear();
// 發(fā)起反地理編碼檢索
mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
.location(mLoactionLatLng));
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mLocationClient.stop();
mGeoCoder.destroy();
}
// 定位監(jiān)聽器
private class MyBDLocationListner implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// TODO Auto-generated method stub
// map view 銷毀后不在處理新接收的位置
if (location == null || mMapView == null)
return;
MyLocationData data = new MyLocationData.Builder()//
// .direction(mCurrentX)//
.accuracy(location.getRadius())//
.latitude(location.getLatitude())//
.longitude(location.getLongitude())//
.build();
mBaiduMap.setMyLocationData(data);
// 設(shè)置自定義圖標(biāo)
MyLocationConfiguration config = new MyLocationConfiguration(
LocationMode.NORMAL, true, null);
mBaiduMap.setMyLocationConfigeration(config);
mLantitude = location.getLatitude();
mLongtitude = location.getLongitude();
LatLng currentLatLng = new LatLng(mLantitude, mLongtitude);
mLoactionLatLng = new LatLng(mLantitude, mLongtitude);
// 是否第一次定位
if (isFirstLoc) {
isFirstLoc = false;
// 實(shí)現(xiàn)動(dòng)畫跳轉(zhuǎn)
MapStatusUpdate u = MapStatusUpdateFactory
.newLatLng(currentLatLng);
mBaiduMap.animateMapStatus(u);
mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
.location(currentLatLng));
return;
}
}
}
// 地理編碼監(jiān)聽器
OnGetGeoCoderResultListener GeoListener = new OnGetGeoCoderResultListener() {
public void onGetGeoCodeResult(GeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
// 沒有檢索到結(jié)果
}
// 獲取地理編碼結(jié)果
}
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
// 沒有找到檢索結(jié)果
}
// 獲取反向地理編碼結(jié)果
else {
// 當(dāng)前位置信息
mCurentInfo = new PoiInfo();
mCurentInfo.address = result.getAddress();
mCurentInfo.location = result.getLocation();
mCurentInfo.name = "[位置]";
mInfoList.clear();
mInfoList.add(mCurentInfo);
// 將周邊信息加入表
if (result.getPoiList() != null) {
mInfoList.addAll(result.getPoiList());
}
// 通知適配數(shù)據(jù)已改變
mAdapter.notifyDataSetChanged();
mLoadBar.setVisibility(View.GONE);
}
}
};
// 地圖觸摸事件監(jiān)聽器
OnMapTouchListener touchListener = new OnMapTouchListener() {
@Override
public void onTouch(MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mCenterPoint == null) {
return;
}
// 獲取當(dāng)前MapView中心屏幕坐標(biāo)對(duì)應(yīng)的地理坐標(biāo)
LatLng currentLatLng;
currentLatLng = mBaiduMap.getProjection().fromScreenLocation(
mCenterPoint);
System.out.println("----" + mCenterPoint.x);
System.out.println("----" + currentLatLng.latitude);
// 發(fā)起反地理編碼檢索
mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
.location(currentLatLng));
mLoadBar.setVisibility(View.VISIBLE);
}
}
};
// listView選項(xiàng)點(diǎn)擊事件監(jiān)聽器
OnItemClickListener itemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
// 通知是適配器第position個(gè)item被選擇了
mAdapter.setNotifyTip(position);
BitmapDescriptor mSelectIco = BitmapDescriptorFactory
.fromResource(R.drawable.icon_geo);
mBaiduMap.clear();
PoiInfo info = (PoiInfo) mAdapter.getItem(position);
LatLng la = info.location;
// 動(dòng)畫跳轉(zhuǎn)
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(la);
mBaiduMap.animateMapStatus(u);
// 添加覆蓋物
OverlayOptions ooA = new MarkerOptions().position(la)
.icon(mSelectIco).anchor(0.5f, 0.5f);
mBaiduMap.addOverlay(ooA);
// 選中項(xiàng)打勾
mSelectImg.setBackgroundResource(R.drawable.greywhite);
mSelectImg = (ImageView) view.findViewById(R.id.place_select);
mSelectImg.setBackgroundResource(R.drawable.ic_select);
// Uri mUri = Uri.parse("geo:39.940409,116.355257");
// Intent mIntent = new Intent(Intent.ACTION_VIEW,mUri);
// startActivity(mIntent);
}
};
}
自定義的listView適配器
package com.vr.souhuodong.UI.Adapter;
import java.util.List;
import android.R.integer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.baidu.mapapi.search.core.PoiInfo;
import com.vr.souhuodong.R;
public class PlaceListAdapter extends BaseAdapter {
List<PoiInfo> mList;
LayoutInflater mInflater;
int notifyTip ;
private class MyViewHolder {
TextView placeName;
TextView placeAddree;
ImageView placeSelected;
}
public PlaceListAdapter(LayoutInflater mInflater , List<PoiInfo> mList) {
super();
this.mList = mList;
this.mInflater = mInflater;
notifyTip = -1 ;
}
/**
* 設(shè)置第幾個(gè)item被選擇
* @param notifyTip
*/
public void setNotifyTip(int notifyTip) {
this.notifyTip = notifyTip;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mList.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mList.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
MyViewHolder holder;
if (convertView == null) {
System.out.println("----aa-");
convertView = mInflater.inflate(com.vr.souhuodong.R.layout.listitem_place, parent, false);
holder = new MyViewHolder();
holder.placeName = (TextView) convertView
.findViewById(com.vr.souhuodong.R.id.place_name);
holder.placeAddree = (TextView) convertView
.findViewById(com.vr.souhuodong.R.id.place_adress);
holder.placeSelected = (ImageView) convertView
.findViewById(com.vr.souhuodong.R.id.place_select);
holder.placeName.setText(mList.get(position).name);
holder.placeAddree.setText(mList.get(position).address);
holder.placeSelected.setBackgroundResource(R.drawable.greywhite);
convertView.setTag(holder);
} else {
holder = (MyViewHolder) convertView.getTag();
}
holder.placeName.setText(mList.get(position).name);
holder.placeAddree.setText(mList.get(position).address);
//根據(jù)重新加載的時(shí)候第position條item是否是當(dāng)前所選擇的,選擇加載不同的圖片
if(notifyTip == position ){
holder.placeSelected.setBackgroundResource(R.drawable.ic_select);
}
else {
holder.placeSelected.setBackgroundResource(R.drawable.greywhite);
}
return convertView;
}
// class MyItemClickListener implements OnClickListener {
//
// ImageView mImg;
// public MyItemClickListener(ImageView mImg) {
// this.mImg = mImg;
// }
// @Override
// public void onClick(View v) {
// // TODO Auto-generated method stub
// mImg.setBackgroundResource(R.drawable.ic_select);
// }
//
// }
}
總結(jié)
以上所述是小編給大家介紹的利用百度地圖Android sdk高仿微信發(fā)送位置功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Android之使用Android-query框架開發(fā)實(shí)戰(zhàn)(二)
這篇文章主要介紹了Android之使用Android-query框架開發(fā)實(shí)戰(zhàn)(二)的相關(guān)資料,需要的朋友可以參考下2015-10-10
Android 跨進(jìn)程SharedPreferences異常詳解
這篇文章主要介紹了Android 跨進(jìn)程SharedPreferences異常詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android API開發(fā)之SMS短信服務(wù)處理和獲取聯(lián)系人的方法
這篇文章主要介紹了Android API開發(fā)之SMS短信服務(wù)處理和獲取聯(lián)系人的方法,結(jié)合實(shí)例形式分析了Android API實(shí)現(xiàn)SMS短信發(fā)送及獲取聯(lián)系人的相關(guān)操作步驟與實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-08-08
Android 虛擬按鍵適配動(dòng)態(tài)調(diào)整布局的方法
今天小編就為大家分享一篇Android 虛擬按鍵適配動(dòng)態(tài)調(diào)整布局的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07
詳解Android中Service服務(wù)的基礎(chǔ)知識(shí)及編寫方法
這篇文章主要介紹了詳解Android中Service服務(wù)的基礎(chǔ)知識(shí)及編寫方法,包括Service的啟動(dòng)流程及生命周期等基本內(nèi)容,需要的朋友可以參考下2016-04-04
解決Android SELinux權(quán)限問題記錄分析
這篇文章主要為大家介紹了解決Android SELinux權(quán)限問題記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11

