com.baidu map api.mapapi.map.mapview无法实例化

百度地图API使用,结合聚合数据 - 简书
下载简书移动应用
写了61760字,被101人关注,获得了93个喜欢
百度地图API使用,结合聚合数据
之前研究了一下百度地图的API,做一个类似附近的XX的功能,整体上接口还是很好用的,用到了定位,地图,云存储和云检索,全景图和路径规划,导航没有加进去,期间也遇到了许多未知的困难,通过论坛提问,加群,和相关负责人请教得以解决;
1.首先得有百度账号,然后注册成为开发者,然后就可以申请ak了;
在后台创建一个安卓应用,需要安全码,格式是SHA1值加分号加包名,ADT默认使用的是debug.keystore,我们一般发布产品的时候都会使用自己的签名,就是另一个keystore,如果用的是默认,直接在ADT里面设置-&Android-&build里面就能看到SHA1,如果是自己的keystore,那么有2种方法:
(1).根据我们的签名文件制作出一个debugkeystore(这个以后都可以通用,而且不只是用于百度地图),然后直接在ADT中选择就可以显示出来了,Preference-&Android-&Build里面,下面说一下如何制作debugkeystore:
a. 将密码改为android:
keytool -storepasswd -keystore XXX.keystore
b. 将别名修改为androiddebugkey:
keytool -changealias -keystore XXX.keystore -alias XXXname -destalias androiddebugkey
c. 修改alias的密码为android:
keytool -keypasswd -keystore XXX.keystore -alias androiddebugkey
如果没有配置环境变量,那么其中keytool是.android下的命令(一般在C:\Users\Administrator),keystore是你放文件的路径,这样就制作出了一个debugkeystore,在ADT里面选择就可以获取SHA1值了;
(2).命令行操作获取:也可以参考
cd .android
keytool -list -v -keystore debug.keystore
得到SHA1值之后,我们就可以随意为多个项目使用,只要和包名组合就可以得到一个ak,所以ak只是一个身份认证,如果有多个程序,可以一次性申请完成; 这个ak是作为应用的标识的,还可以统计数据,一般第三方都会有的,聚合数据还会根据key进行收费和免费;
2.接下来我们就可以配置百度地图了,,这里可以有选择的去下载以减小app体积,下面说说配置demo,主要还是在ak上面,用百度地图demo的包名加自己的SHA1去重新创建一个app,demo中的地图就能正常显示了;
SDK主要就是libs和so文件,ADT22以上需要特殊处理一下:
1.右键选 Properties-&Java Build Path-&Order and Export
使 Android Private Libraries处于勾选状态;2.Project -& clean-& clean all .
AndroidStudio引用so需要建立jniLibs目录,引用jar需要file dependency,然后往manifest添加key和权限, ;
&meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="ak" /&
接下来在XML中引用地图view;
&com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" /&
测试的话可以在activity的oncreate()里面setcontentview()前执行初始化SDKInitializer.initialize(getApplicationContext());但是真正使用的时候还是把它放到application的oncreate()里面好,因为我们可能不止一处用到地图控件,还会用到其他sdk的初始化,这些都应该在application里面执行;
3.代码级别的使用:添加地图生命周期函数,如果以后用到定位或者其他也都需要生命周期管理
MapView mMapView = (MapView) findViewById(R.id.bmapView);
BaiduMap mBaiduMap = mMapView.getMap();
protected void onResume() {
super.onResume();
mMapView.onResume();
protected void onPause() {
super.onPause();
mMapView.onPause();
protected void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
可以设置中心点为指定显示,默认是显示北京
LatLng p = new LatLng(102.2);
mMapView = new MapView(this,
new BaiduMapOptions().mapStatus(
new MapStatus.Builder().target(p).build()));
如果在fragment里面使用请看MapFragment,不要直接强转
public class MapFragmentDemo extends FragmentActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
MapStatus ms = new MapStatus.Builder().overlook(-20).zoom(15).build();
BaiduMapOptions bo = new BaiduMapOptions().mapStatus(ms)
.compassEnabled(false).zoomControlsEnabled(false);
SupportMapFragment map = SupportMapFragment.newInstance(bo);
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().add(R.id.map, map, "map_fragment").commit();
地图的一些基本属性设置:
//普通地图
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
//卫星地图
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
//开启交通图
mBaiduMap.setTrafficEnabled(true);
//开启热力图
mBaiduMap.setBaiduHeatMapEnabled(true);
//是否允许缩放
mMapView.showScaleControl(false);
//不显示放大缩小框
mMapView.showZoomControls(false);
点击地图点
mBaiduMap.setOnMapClickListener(new OnMapClickListener() {
public void onMapClick(LatLng point) {
public boolean onMapPoiClick(MapPoi poi) {
4.下面来聊聊附件的XX需要怎么实现:首先进入程序之后开启定位,定位成功后在地图上显示位置,然后进行检索,把检索出来的结果标注在地图上,点击某个标注可以跳转到详情页,显示一个全景图和路径规划和一些其他的信息;
定位功能的实现:定位成功回调后给地图设置显示的点,同时还可以设置一个缩放
// 位置回调接口
BDLocationListener locationListener = new MyLocationListener();
client = new LocationClient(this);
client.registerLocationListener(locationListener);
LocationClientOption option2 = new LocationClientOption();
option2.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
// 是否需要打开GPS
// option2.setOpenGps(true);
option2.setCoorType("bd09ll");
option2.setScanSpan(60000);
client.setLocOption(option2);
class MyLocationListener implements BDLocationListener {
MapStatus mMapS
MyLocationData locD
public void onReceiveLocation(BDLocation bdLocation) {
location = bdL
// 构造定位数据
locData = new MyLocationData.Builder()
// 定位经度
.accuracy(location.getRadius())
.direction(location.getDirection())
.latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
// 设置缩放
mMapStatus = new MapStatus.Builder()
.target(new LatLng(location.getLatitude(),
location.getLongitude())).zoom(16).build();
// 设置定位数据
mBaiduMap.setMyLocationData(locData);
MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
// 改变地图状态
mBaiduMap.setMapStatus(mMapStatusUpdate);
//执行搜索
//search(2000);
检索这一块比较繁琐,主要是感觉文档写的和代码不一致,很困惑,首先我们需要构建数据库,如果自己用后台建立数据库可以,还要自己写一个根据传来的经纬度去查找附近的点的算法,但是百度提供了云存储功能,很简洁,他需要一个csv格式的Excel或者使用网页版建表,我们需要建立这么一个表;
如果数据量比较少,自己试着用,可以在百度云API后台页面进行添加,直接在地图上面选点,添加属性,有几个必填的属性,还有coord_type要填3,意味着采用百度坐标(这个问题时候来使用全景图的时候发现根本不匹配,找坛主解决的);
如果数据量很多或者需要定制,那么就要自己去构建这么一个表,详细说说这一部分;
现在假设用户给了我100个地址,只有文字,我要如何建表呢,我之前试了一些批量转的工具,要么是收费的要么是顺序不对,后来直接在程序里面使用百度geo自己做了;
首先把这一串文字地址写成一个txt,一行一条,同时每一条最好都以XX市开头,这样更精确, 放到手机上;
写一个方法去读这个txt文件,一次读一行获得一个Arraylist&String&;
然后去使用地图geo相关api去解析它,于是我用了一个for循环去请求,只返回了一条,因为一次请求太多了,后来想用一个队列去试试,最后用了定时器做的,每隔1秒去执行一次请求,把返回的经纬度用逗号连接起来组成新的Arraylist&String&,最后把他写入txt文件里面;
把文件从手机传到电脑上,复制到excel表格里面,在excel里面检查缺少的数据(如果有需要单独去解析缺少的条目,可以使用百度提供的网站工具),以逗号为标识分列,合成最终的表,导出csv格式后上传,这里也可以自定义或扩展一些其他的业务属性;
//读取txt文件的内容
ArrayList&String& templist = new ArrayList&&();
public void 读取文本(String filePath) {
String encoding = "UTF-8";
File file = new File(filePath);
//判断文件是否存在
if (file.isFile() && file.exists()) {
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), encoding);
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt =
while ((lineTxt = bufferedReader.readLine()) != null) {
templist.add(lineTxt);
// Log.e("", lineTxt);
read.close();
Log.e("", templist.size() + "");
for (int i = 0; i & templist.size(); i++) {
// Log.e("", templist.get(i) + "");
Log.e("", "找不到指定的文件");
} catch (Exception e) {
Log.e("", "读取文件内容出错");
e.printStackTrace();
StringBuffer b = new StringBuffer();
int q = 0;
//队列也很好使用,queue.poll();queue.offer();
//Queue&String& queue = new LinkedList&&();
//Map&String, String& map = new HashMap&String, String&();
//记position需要一个全局的变量
void 批处理() {
timer = new Timer(true);
new AsyncTask&Void, Void, Void&() {
protected Void doInBackground(Void... voids) {
//读取txt文件,读到换行符的时候list加一项
读取文本(Environment.getExternalStorageDirectory().toString() + "/Pictures/" + "h.txt");
for (int i = 0; i & templist.size(); i++) {
Log.e("", templist.get(i));
//定时器这里不是用for循环来做的
timer.schedule(new TimerTask() {
public void run() {
str = templist.get(q++);
mSearch.geocode(new GeoCodeOption().city("济宁").address(str));
}, 5000, 1 * 1000);
//开启服务5秒后启动线程,并且每1秒循环一次
}.execute();
//回调geo结果,先让类实现接口 implements OnGetGeoCoderResultListener
//给文字获得经纬度,搜索模块,也可去掉地图模块独立使用
GeoCoder mSearch =
// 初始化搜索模块,注册事件监听,生命周期销毁
mSearch = GeoCoder.newInstance();
mSearch.setOnGetGeoCodeResultListener(this);
mSearch.destroy();
//获取到了结果之后存成txt,整理excel
public void onGetGeoCodeResult(GeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(MapActivity.this, "抱歉,未能找到结果", Toast.LENGTH_LONG).show();
mBaiduMap.clear();
mBaiduMap.addOverlay(new MarkerOptions().position(result.getLocation())
.icon(BitmapDescriptorFactory
.fromResource(R.mipmap.icon_marka)));
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(result
.getLocation()));
b.append(String.format("纬度:%f
经度:%f",
result.getLocation().latitude, result.getLocation().longitude));
b.append(q + "纬度:" + result.getLocation().latitude + ",
经度:" + result.getLocation().longitude + "\n");
//debug开始
//String strInfo = String.format("纬度:%f
经度:%f",
//result.getLocation().latitude, result.getLocation().longitude);
//Log.e("", String.format("纬度:%f
经度:%f",
//result.getLocation().latitude, result.getLocation().longitude));
//debug结束
if (q == templist.size()) {
timer.cancel();
保存文本文件(Environment.getExternalStorageDirectory().toString() + "/Pictures/", "result.txt", b.toString());
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(MapActivity.this, "抱歉,未能找到结果", Toast.LENGTH_LONG).show();
public static void 保存文本文件(String path, String filename, String string) {
// 创建目录
isFileExistAndCreat(path);
File targetFile = new File(path + filename);
OutputStreamW
// 创建文件
if (!targetFile.exists()) {
targetFile.createNewFile();
osw = new OutputStreamWriter(new FileOutputStream(targetFile), "UTF-8");
osw.write(string);
osw.close();
// 再次写入时不采用拼接的方法,而是重新写
osw = new OutputStreamWriter(new FileOutputStream(targetFile, false), "UTF-8");
osw.write(string);
osw.flush();
osw.close();
} catch (Exception e) {
//判断文件是否存在,不存在则创建
public static void isFileExistAndCreat(String filepath) {
if (isSdcardAvailable()) {
File file = new File(filepath);
if (!file.exists()) {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
//检查SD卡是否可用
public static boolean isSdcardAvailable() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
云存储搞完了就剩下云检索了,这里首先在创建一个服务器应用,获取AK,因为云检索V3版本需要申请服务器的AK才能使用,但我们不需要有服务器;然后就是引入jar包,在application里面初始化:CloudManager.getInstance().init(this); 并实现CloudListener,添加如下2个方法
// 获取到搜索结果后添加标记
public void onGetSearchResult(CloudSearchResult result, int error) {
//可选清空地图,我这里要加标注
mBaiduMap.clear();
//result里面封装了一系列的point的list
if (result != null && result.poiList != null&& result.poiList.size() & 0) {
//这里我的数据库里有2种类型的点,所以创建了2类图片标注
BitmapDescriptor bd1 = BitmapDescriptorFactory.fromResource(R.drawable.icon_marka);
BitmapDescriptor bd2 = BitmapDescriptorFactory.fromResource(R.drawable.icon_markb);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
//这里我是定义了一个全局变量的数组存放标注的点
markerx = new Marker[result.poiList.size()];
for (int i = 0; i & result.poiList.size(); i++) {
//如果你不需要这些功能,直接从这里取数据就可以了
CloudPoiInfo cloudPoiInfo = result.poiList.get(i);
//这是我定义的一个实体类,和我的数据库相对应
Enerty enerty = new Enerty(
cloudPoiInfo.title,cloudPoiInfo.address, cloudPoiInfo.latitude,cloudPoiInfo.longitude);
//这里是表格里面自定义属性的用法
Map&String, Object& map = cloudPoiInfo.
enerty.setPerson((String) map.get("person"));
enerty.setPhone((String) map.get("phone"));
String typeString = (String) map.get("types");
enerty.setType(typeString);
enertyArrayList.add(enerty);
ll = new LatLng(cloudPoiInfo.latitude,cloudPoiInfo.longitude);
if (typeString.equals("1")) {
oo = new MarkerOptions().icon(bd1).position(ll);
oo = new MarkerOptions().icon(bd2).position(ll);
//这里给数组赋值
markerx[i] = (Marker) mBaiduMap.addOverlay(oo);
builder.include(ll);
//添加圆,是指标记一个范围,如附近200米
LatLng llCircle = new LatLng(location.getLatitude(),
location.getLongitude());
OverlayOptions ooCircle = new CircleOptions().fillColor(0x3054FF9F)
.center(llCircle).stroke(new Stroke(5, 0x3033cccc))
.radius(1200);
//给地图添加标注点
mBaiduMap.addOverlay(ooCircle);
} catch (Exception e) {
public void onGetDetailSearchResult(DetailSearchResult result, int error) {
if (result != null) {
if (result.poiInfo != null) {
Toast.makeText(MapActivity.this,result.poiInfo.title,Toast.LENGTH_SHORT).show();
Toast.makeText(MapActivity.this, "status:"+error,Toast.LENGTH_SHORT).show();
把点添加到地图上之后就可以点击了,点击弹出一个popwindow显示简介,点击popwindow跳到详情页;
// 点击标注弹出layout,点击layout的事件
mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
public boolean onMarkerClick(final Marker marker2) {
Button button = new Button(MapActivity.this);
button.setBackgroundResource(R.drawable.popmap);
InfoWindow.OnInfoWindowClickListener listener =
for (int i = 0; i & markerx. i++) {
if (marker2 == markerx[i]) {
button.setText(enertyArrayList.get(i).getName());
listener = new InfoWindow.OnInfoWindowClickListener() {
public void onInfoWindowClick() {
mBaiduMap.hideInfoWindow();
Intent intent = new Intent(MapActivity.this,
DetailActivity.class);
intent.putExtra("p", enertyArrayList.get(p));
if (DEBUG) {
intent.putExtra("lat", 35.);
intent.putExtra("lon", 116.);
intent.putExtra("lat",location.getLatitude());
intent.putExtra("lon",location.getLongitude());
startActivity(intent);
AnimUtil.animToSlide(MapActivity.this);
LatLng ll = marker2.getPosition();
mInfoWindow = new InfoWindow(BitmapDescriptorFactory
.fromView(button), ll, -47, listener);
mBaiduMap.showInfoWindow(mInfoWindow);
至于详情页的显示那就是全景图和导航的一些API了,这里还有一些我刚开始用到的一些方法
//构建测试数据,浮点数的格式化,随机数
ArrayList&Enerty& initData() {
ArrayList&Enerty& enertyArrayList = new ArrayList&Enerty&();
Random rd1;
BigDecimal temp1, temp2, lat,
if (enertyArrayList.size() == 0) {
for (int i = 0; i & 10; i++) {
temp1 = new BigDecimal(rd1.nextDouble() * 0.05 + 36.651216);
lat = temp1.setScale(6, RoundingMode.DOWN);
temp2 = new BigDecimal(rd1.nextDouble() * 0.1 + 117.081125);
lon = temp2.setScale(6, RoundingMode.DOWN);
Enerty enerty1 = new Enerty("辰欣药" + i, "环城路" + i, lat.doubleValue(), lon.doubleValue());
enertyArrayList.add(enerty1);
return enertyArrayL
//添加一个标记返回一个marker
public void setMarkers() {
LatLng point = new LatLng(39.6.400244);
//构建Marker图标
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher);
//构建MarkerOption,用于在地图上添加Marker
OverlayOptions options = new MarkerOptions()
.position(point)
//设置marker的位置
.icon(bitmap)
//设置marker图标
.zIndex(9)
//设置marker所在层级
.draggable(true);
//设置手势拖拽
//将marker添加到地图上
Marker marker = (Marker)(mBaiduMap.addOverlay(options));
//调用BaiduMap对象的setOnMarkerDragListener方法设置marker拖拽的监听
mBaiduMap.setOnMarkerDragListener(new BaiduMap.OnMarkerDragListener() {
public void onMarkerDrag(Marker marker) {
public void onMarkerDragEnd(Marker marker) {
//拖拽结束
public void onMarkerDragStart(Marker marker) {
//开始拖拽
研究第三方的SDK出了问题怎么办,去论坛发帖,搜索相关内容,加群;由于版本更新导致很多问题,不要在意新旧版本,能用就行;文档和demo中的代码不一致,以代码为主;不要把诸多测试样例放一起;百度提供了混淆的相关配置写法;
一种直接用android操作excel的方法
public class BdCodingActivity extends Activity implements OnGetGeoCoderResultListener {
GeoCoder mS
TextView tv_
Button bt_
int totalC
Timer timer = new Timer(true);
Sheet readS
WritableSheet writeS
protected void onCreate(Bundle savedInstanceState) {
SDKInitializer.initialize(getApplicationContext());
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bdcoding);
tv_code = (TextView) findViewById(R.id.tv_bdcode);
bt_uploadpois = (Button) findViewById(R.id.bt_uploadpois);
mSearch = GeoCoder.newInstance();
mSearch.setOnGetGeoCodeResultListener(this);
File dataFile = new File(Environment.getExternalStorageDirectory().getPath() + "/hrss_data.xls");
wb = Workbook.getWorkbook(dataFile);
readSheet = wb.getSheet(0);
totalCount = readSheet.getRows();
wbook = Workbook.createWorkbook(dataFile, wb);
writeSheet = wbook.getSheet(0);
} catch (Exception e) {
tv_code.setText("获取xls文件异常," + e.getMessage());
int i = 0;
public void gainGeoCode(View v) {
timer.schedule(new TimerTask() {
public void run() {
String address = readSheet.getCell(1, i).getContents();
if(TextUtils.isEmpty(address)){
address = readSheet.getCell(0, i).getContents();
mSearch.geocode(new GeoCodeOption().city("威海").address(address));
}, );//开启服务1秒后启动线程,并且每两秒循环一次
protected void onDestroy() {
mSearch.destroy();
super.onDestroy();
public void onGetGeoCodeResult(GeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
tv_code.setText("第" + i + "条未能找到结果");
String strInfo = String.format("纬度:%f 经度:%f", result.getLocation().latitude, result.getLocation().longitude);
tv_code.setText("第" + i + "条," + strInfo);
writeSheet.addCell(new Label(2, i - 1, String.valueOf(result.getLocation().longitude)));
writeSheet.addCell(new Label(3, i - 1, String.valueOf(result.getLocation().latitude)));
} catch (Exception e) {
tv_code.setText("写excel异常" + e.getMessage());
if(i == totalCount){
wbook.write();
wbook.close();
} catch (Exception e) {
e.printStackTrace();
timer.cancel();
bt_uploadpois.setVisibility(View.VISIBLE);
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Log.w("BAIDU", "抱歉,未能找到结果");
Log.v("BAIDU", result.getAddress());
tv_code.setText(result.getAddress());
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:下次自动登录
现在的位置:
& 综合 & 正文
基于百度地图API开发问题集合
1、屏幕坐标转换经纬度
//将像素坐标转为地址坐标
Projection mProjection = BMapView.getProjection();
GeoPoint pt = mProjection.fromPixels((int)touchX,(int)touchY);
2、替换搜索结果覆盖物的样式
(1)创建OverItemT,继承ItemizedOverlay&OverlayItem&
import java.util.ArrayL
import android.graphics.C
import android.graphics.drawable.D
import com.baidu.mapapi.ItemizedO
import com.baidu.mapapi.MapV
import com.baidu.mapapi.OverlayI
public class OverItemT extends ItemizedOverlay&OverlayItem& {
private ArrayList&OverlayItem& mOverlays = new ArrayList&OverlayItem&();
//defaultMarker替换百度API中覆盖物样式
public OverItemT(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
public int size() {
return mOverlays.size();
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
protected boolean onTap(int index) {
return super.onTap(index);
(2)把覆盖物添加到MapView上,用invalidate刷新
OverItemT overlay = new OverItemT(drawable);
for (int i = 0; i & res.getAllPoi().size(); i++) {
OverlayItem item = new OverlayItem(res.getPoi(i).pt,
"站点", "站点信息"); // 点,标题,文字片段。
overlay.addOverlay(item);
BMapView.getOverlays().clear();
BMapView.getOverlays().add(overlay);
BMapView.invalidate();
3、处理地图长按、轻触、滑动等事件
(1)由于地图上有各种手势事件触发,那么我们会用到GestureDetector来处理这些事情,下面介绍GestureDetector:
GestureDetector里面会实现以下方法:
onSingleTapUp、onShowPress、onScroll、onLongPress、onFling、onDown
这些方法都是由MotionEvent触发的。
onSingleTapUp
用户轻触屏幕后松开,由ACTION_UP触发,事件执行顺序为onDown-&onShowPress-&onSingleTapUp。
onShowPress 用户轻触屏幕后,没有任何的松动或拖动才会触发,由ACTION_DOWN触发,与onDown的区别是,onDown只要用户触摸触摸屏就会触发,若松动或拖动,就不会触发onShowPress,反之,则触发。
onLongPress
顾名思义,用户长时间触摸屏幕,由ACTION_DOWN触发,事件执行顺序为onDown-&onShowPress-&onLongPress。
onFling 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发
(2)现在,我们定义一个长按层 LongPressOverlay:
这里需要注意一点,想让自定义的View实现各种手势,需设置onTouchEvent,gestureDetector.onTouchEvent(event);
各个实现方法,由具体需要自己修改即可,这里我处理的是长按事件!
构造方法中的Handler,用途是处理长按以后的事件,把一些覆盖物放置在地图上;我在handler中做的是搜索触摸点1公里范围内的公交站点,并显示在地图上。
import com.baidu.mapapi.MapC
import com.baidu.mapapi.MapV
import com.baidu.mapapi.O
import com.buscall.ui.MapS
import android.os.H
import android.view.GestureD
import android.view.GestureDetector.OnDoubleTapL
import android.view.GestureDetector.OnGestureL
import android.view.MotionE
* @ClassName: LongPressOverlay
* @Descrioption: 地图长按层
* @author LiZhen
public class LongPressOverlay extends Overlay implements OnDoubleTapListener,OnGestureListener{
private MapSearch mC
private MapView mMapV
private Handler mH
private GestureDetector gestureScanner = new GestureDetector(this);
public LongPressOverlay(MapSearch context, MapView mapView, Handler handler,MapController mapCtrl){
mContext =
mMapView = mapV
mHandler =
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
mContext.touchX = event.getX();
mContext.touchY = event.getY();
return gestureScanner.onTouchEvent(event);
public boolean onSingleTapConfirmed(MotionEvent e) {
public boolean onDoubleTap(MotionEvent e) {
public boolean onDoubleTapEvent(MotionEvent e) {
public boolean onDown(MotionEvent e) {
public void onShowPress(MotionEvent e) {
public boolean onSingleTapUp(MotionEvent e) {
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
public void onLongPress(MotionEvent e) {
mContext.locPoint = mMapView.getProjection().fromPixels((int) e.getX(),
(int) e.getY());
mHandler.sendEmptyMessage(mContext.MSG_VIEW_LONGPRESS);
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
(3)MapActivity中添加长按层和编写Handler
把下面这句话加在onCreate中,
BMapView.getOverlays().add(new LongPressOverlay(MapSearch.this, BMapView, mHandler, mMapController));
在这简单的定义Handler了,如下:
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_VIEW_LONGPRESS:// 处理长按时间返回位置信息
System.out.println("附近站点个数:" + overlay.size());
CircleOverlay circle = new CircleOverlay(pt, MapSearch.this);
BMapView.getOverlays().clear();
BMapView.getOverlays().add(overlayRemind);
BMapView.getOverlays().add(mylocTest);
BMapView.getOverlays().add(overlay);
BMapView.getOverlays().add(circle);
BMapView.getOverlays().add(new LongPressOverlay(MapSearch.this, BMapView, mHandler, mMapController));
BMapView.invalidate();
if (c.getCount() & 0)
BMapView.getController().animateTo(pt);
case UPDATEUI:
到这就实现了长按事件!
4、点击OverlayItem,弹出信息层,如上图所示:点击像站牌的小图标,弹出“光华桥西”字样的信息框
(1)要知道,这个点击事件是在ItemizedOverlay类中的onTap(int index),index表示按的是具体哪个OverlayItem,所以处理事件在这里编写;
public class OverItemT extends ItemizedOverlay&OverlayItem& {
private ArrayList&OverlayItem& mOverlays = new ArrayList&OverlayItem&();
private MapSearch mC
//defaultMarker替换百度API中覆盖物样式
public OverItemT(Drawable defaultMarker , Context context) {
super(boundCenterBottom(defaultMarker));
this.mContext = (MapSearch)
public int size() {
return mOverlays.size();
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
protected boolean onTap(int index) {
return super.onTap(index);
(2)编写popView.xml,样式如下:
关于上面显示的每个item信息从何而来呢?
注意OverlayItem的构造方法:
point, java.lang.String title, java.lang.String snippet)
参数分别代表 点、标题、文字,我们可以把item的信息存储在这里。
只需设置popView的显示与隐藏,就可以实现效果
这样我们就做好了弹出信息框。
5、搜索sqlite数据库中,范围1公里的公交站点
经度0.0009代表100米
纬度0.0012代表100米
sql语句为:select * from
api_station where ((abs(XCoord-?)/0.0012)*(abs(XCoord-?)/0.0012) + (abs(YCoord-?)/0.0009)*(abs(YCoord-?)/0.0009))&100;
没有找到sqlite中平方用什么方法,只好上面这么写了。
6、真实经纬度数据转化成百度地图的经纬度数据,标识在地图上
将其他坐标系转换到百度坐标系,自V1.1版本之后提供
包:com.baidu.mapapi
类:CoordinateConvert
接口摘要说明:
fromWgs84ToBaidu()
从gps坐标系或mapbar坐标系转换到百度坐标系,
返回结果为经过Base64加密之后字符串
fromGcjToBaidu()
从google坐标系、51地图坐标系、mapcabc坐标系转换到百度坐标系(51地图坐标需要先除10000),
返回结果为经过Base64加密之后的字符串
bundleDecode()
加密bundle到坐标的转换函数
详细说明:
fromWgs84ToBaidu
static public Bundle fromWgs84ToBaidu(GeoPoint ptWgs84)
从gps坐标系或mapbar坐标系转换到百度坐标系.
ptWgs84- gps坐标或mapbar坐标
返回bundle,内含x,y两个字段。均为经过Base64加密之后的字符串,可调用bundleDecode()函数进行解析
fromGcjToBaidu
static public Bundle fromGcjToBaidu
(GeoPoint ptGcj)
从google坐标系、51地图坐标系、mapabc坐标系转换到百度坐标系.<span style="color:#地图坐标需要先除<span style="color:#000
ptGcj- google坐标或mapabc坐标或51地图坐标(51地图坐标需要先除10000)
返回bundle,内含x,y两个字段。均为经过Base64加密之后的字符串,可调用bundleDecode()函数进行解析
bundleDecode
static public GeoPoint bundleDecode(Bundle encryptBundle)
将加密之后的坐标bundle进行解析
encryptBundle – 加密后的坐标bundle
返回GeoPoint结构,内含解析之后的x,y坐标
该类提供的转换函数仅供获得授权后的厂商或开发者使用,禁止在公共网站,论坛或其他公共场合进行公布或宣传。
CoordinateConvert coordinateConvert = new CoordinateConvert();
Bundle bundle = coordinateConvert.fromWgs84ToBaidu(gp);
int x = coordinateConvert.bundleDecode(bundle).getLatitudeE6();
int y = coordinateConvert.bundleDecode(bundle).getLongitudeE6();
System.out.println(x+" , "+y);
7、捕获百度地图平移结束事件
MapView.regMapViewListener(BMapManager, new mMKMapViewListener());
class mMKMapViewListener implements MKMapViewListener{
public void onMapMoveFinish() {
// ...处理地图平移结束后的操作
&&&&推荐文章:
【上篇】【下篇】

我要回帖

更多关于 baidumapapi v3 5 0 的文章

 

随机推荐