Android学习笔记之使用LBS实现定位
PS:最近一直在搞使用LBS实现定位.一般现在涉及到日常生活交易平台的app.貌似都需要使用定位.比如说美团外卖,我请客等app.
学习内容:
1.LBS定位的简单介绍.
2.在Map上添加地图覆盖物+地理编码+反地理编码
1.LBS定位的简单介绍
LBS:基站定位.我这里主要还是通过使用百度地图LBS实现定位.使用百度地图LBS实现定位需要做一些相关的准备工作.需要在LBS开放平台上注册自己的AK.有了这个AK.我们的应用才能够去调用百度地图的LBS去实现定位功能.
百度地图LBS:AK注册地址:http://lbsyun.baidu.com/apiconsole/key.
我们注册了LBS的账号之后就可以去创建应用的AK了.这里注册需要添加数字签名.数字签名的获取我直接说一种直接了当的方式.就是通过下图去查找.
黄圈部分就是我们需要添加的数字签名.这是最快也是最直接的方式.还有一种方式是通过cmd的方式进行获取.不过比较麻烦.我一般是使用这种方式去获取的.当输入了数字签名和包名之后.就会出现:
我们可以看到相关应用对应的AK.有了这个AK之后我们的应用才能够去调用.否则是无法实现定位的.那么这个AK的作用是使用在AndroidManifest文件当中的..
<application
<!--name 可以自己命名
value 就是我们获取的AK-->
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="0FFf1eth8qPtRnGakNXqAXkN"/>
</application>
配置的方式如上.在application标签之间进行添加即可..同时我们还需要添加相关的权限.
<!-- 百度API所需权限 -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
这是一些配置信息.我们还需要使用相关的jar包.导入了相应的jar包和.so文件之后.我们才能够真正的在自己的应用上进行相关的开发.需要使用的相关文件如下:
这里我们可以看到使用到了(.so)文件,这个文件其实是动态函数库.只不过是属于C语言层次的.jar包是Java层的一些相关接口.而.so文件则是linux c层的函数库.这里已经不仅仅是涉及到软件层次上的东西了.已经涉及到了Android内部组件的使用.内部硬件的使用自然要通过C语言去调用.因此(.so)文件是必须要使用的.相应的jar包和(.so)文件包大家可以去网上下载.
那么有了这些基础之后我们就可以真正的去开发我们的定位应用了.
2.在Map上添加地图覆盖物+地理编码+反地理编码
需要明确一个概念 Poi:
BaiDuMap API类中提供了多个类用于我们在地图上添加覆盖物: ArcOptions(弧线形覆盖物),PolygonOptions(多边形覆盖物),TextOptions(文字覆盖物),GroundOverlay(地形图图层覆盖物),PolylineOptions(折线形覆盖物),DotOptions(原点覆盖物),CircleOptions(圆形(空心)覆盖物),这些类都继承与OverlayOptions抽象类
我们在自定义完这些覆盖物之后,通过使用Overlay中的addOverlay()函数,将相应的覆盖物添加到其中就可以完成在地图上添加覆盖物了.
那么覆盖物有什么用?查了很多的资料都没有给我一个明确的概念.个人认为比如说显示一个区域范围内的一些相关的数据信息.那么这个范围就可以通过添加覆盖物去指定区域.从而去显示一个区域内有多少数据信息(比如:房产,某一区域的车辆数等等).
说了这么多.我们就看看如何去添加覆盖物.
i. 多边形覆盖物(PolygonOptions)
覆盖物的添加需要经过几个过程,首先我们需要定义一个坐标点,不难理解.就拿多边形覆盖物来说.我们需要定义多个坐标点.这些坐标点的连线才能够构成多边形.构成多边形之后进行一些属性配置.然后使用Overlay中的addOverlay()函数.就能够成功的在地图上添加覆盖物了.
LatLng pt1 = new LatLng(latitude+0.02,longitude); //参数:经度+纬度
LatLng pt2 = new LatLng(latitude-0.02,longitude); //构造完多个坐标点..
List<LatLng> points =new ArrayList<LatLng>(); //保存节点信息.
PolygonOptions polygonoptions = new PolygonOptions(); //实例化多边形覆盖物对象.
polygonpoints.points(points); //添加坐标点
polygonoptions.fillColor(0xAAFFFF00); //多边形填充颜色
polygonpoints.stroke(new Stroke(2,0xAAFFFF00)); //设置多边形边框信息
Overlay polygon = bdMap.addOverlay(polygonoptions); //添加覆盖物.
这样就可以完成在地图上添加覆盖物.我们也可以为这些覆盖物设置相关的监听事件.监听事件的设置如下..每一个覆盖物都属于Marker的点击事件.因此通过setOnMarkerClickListener就可以实现点击时的相关操作.
bdMap.setOnMarkerClickListener(new OnMarkerClickListener() { @Override
public boolean onMarkerClick(Marker arg0) {
// TODO Auto-generated method stub
final LatLng latLng = arg0.getPosition();
if(arg0 == marker1){
Toast.makeText(getApplicationContext(), latLng.toString(), Toast.LENGTH_SHORT).show();
}
return false;
}
});
PolygonOptions的其他函数
polygonoptions.visiable(boolean visiable); //设置可见性
polygonoptions.zIndex(int zIndex) //设置多边形
polygonoptions.extraInfo(Bundle extraInfo) // 设置多边形额外信息.
ii.TextOptions(文字覆盖物) 设置文字覆盖物需要注意文字的颜色,大小,位置和属性
LatLng latlng = new LatLng(latitude,longitude); 定义坐标点位置
TextOptions textoptions = new TextOptions(); //实例化对象.
//rotate为旋转角度. positions为显示的位置.
textoptions.bgColor(0xAAFFFF00).fontSize(28).fontColor(0xAAFFFF00).text("").rotate(-30).position(latlng);
bdMap.addOverlay(textoptions); //在地图中进行添加 //其他函数:
textoptions.align(int ,int ) 设置文字覆盖物对其方式
textoptions.extra(Bundle);
textoptions.typeface(Typeface); 设置字体
textoptions.zIndex(int zIndex)
textoptions.visiable(boolean visiable)
iii.GroundOverlay(地形图图层覆盖物)
地形图图层可以跟随地图进行平移,深入变换,位于地图和标注图之间,不会遮挡标注图信息.定义这个覆盖物的时候,需要指定宽高.API仅仅提供了两种方法去构建:
1.指定一个(LatLng),再用dimensions方法去指定宽度和高度.
2.使用positionFromBounds(LatLngBounds bounds) 表示一个地理范围.指定两个角坐标构造一个矩形范围.
这里使用到了BitmapDescripter,这个是BaiDuMap中的设置定位图标的方法.这个类主要和Overlay进行打交道,可以为Overlay设置图标信息.
LatLng southwest = new LatLng(latitude - 0.01, longitude - 0.012);//西南
LatLng northeast = new LatLng(latitude + 0.01, longitude + 0.012);//东北
LatLngBounds bounds =new LatLngBounds.Builder().include(southwest).include(northwest).build();//构建对象.
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon); //图标添加.
GroundOverlayOptions options = new GroundOverlayOptions();
options.image(bitmap); //显示的图片
options.positionFromBounds(bounds); //显示位置
options.transparency(0.7f); //显示的透明度
bdMap.addOverlay(options); //添加到地图中
iv.PolylineOptions(折线覆盖物)
折线覆盖物和多边形覆盖物的添加基本相同.需要添加多个坐标点..然后在点与点之间画线.
LatLng pt1 = new LatLng(latitude + 0.01, longitude);
LatLng pt2 = new LatLng(latitude, longitude - 0.01);
LatLng pt3 = new LatLng(latitude - 0.01, longitude - 0.01);
LatLng pt5 = new LatLng(latitude, longitude + 0.01);
List<LatLng> points = new ArrayList<LatLng>();
points.add(pt1);
points.add(pt2);
points.add(pt3);
points.add(pt5);
//
PolylineOptions polylineOptions = new PolylineOptions();
polylineOptions.points(points);
polylineOptions.color(0xFF000000);
polylineOptions.width(4);
bdMap.addOverlay(polylineOptions);
v.DotOptions(原点覆盖物)
原点覆盖物的添加需要定义圆心坐标,以及半径.
private void addDotOptions() {
bdMap.clear();
DotOptions dotOptions = new DotOptions();
dotOptions.center(new LatLng(latitude, longitude));// 设置圆心坐标
dotOptions.color(0XFFfaa755);// 颜色
dotOptions.radius(25);// 设置半径
bdMap.addOverlay(dotOptions);
}
vi.ArcOptions(弧形覆盖物)
弧形覆盖物的添加则需要制定弧的起点,中点,终点..制定了这三个点就可以画出相关的弧线.
private void addArcOptions() {
bdMap.clear();
LatLng pt1 = new LatLng(latitude, longitude - 0.01);
LatLng pt2 = new LatLng(latitude - 0.01, longitude - 0.01);
LatLng pt3 = new LatLng(latitude, longitude + 0.01);
ArcOptions arcOptions = new ArcOptions();
arcOptions.points(pt1, pt2, pt3);// 设置弧线的起点、中点、终点坐标
arcOptions.width(5);// 线宽
arcOptions.color(0xFF000000);
bdMap.addOverlay(arcOptions);
}
vii.CircleOptions(圆形(空心)覆盖物)
圆形空心覆盖物其实和原点覆盖物差不多.只不过一个是实心圆,一个是空心圆.
private void addCircleOptions() {
bdMap.clear();
CircleOptions circleOptions = new CircleOptions();
circleOptions.center(new LatLng(latitude, longitude));// 设置圆心坐标
circleOptions.fillColor(0XFFfaa755);// 圆的填充颜色
circleOptions.radius(150);// 设置半径
circleOptions.stroke(new Stroke(5, 0xAA00FF00));// 设置边框
bdMap.addOverlay(circleOptions);
viii.弹出窗覆盖物.
弹出窗窗口布局我们可以自己去定义.然后添加到Map当中就可以了.
private void displayInfoWindow(final LatLng latLng){ // 创建infowindow展示的view
Button btn = new Button(getApplicationContext());
btn.setBackgroundResource(R.drawable.popup);
btn.setText("");
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromView(btn);
// infowindow点击事件
OnInfoWindowClickListener infoWindowClickListener = new OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick() {
reverseGeoCode(latLng);
//隐藏InfoWindow
bdMap.hideInfoWindow();
}
};
// 创建infowindow
InfoWindow infoWindow = new InfoWindow(bitmapDescriptor, latLng, -47,
infoWindowClickListener); // 显示InfoWindow
bdMap.showInfoWindow(infoWindow);
}
这些都是API为我们提供的相应接口..我们同样可以去自定义样式然后去适配..比如说一个覆盖物的Marker的样式比较复杂..想要使用这个复杂的布局去替换这个bitmap.那么我们就可以将布局转化成bitmap,然后在添加覆盖物的时候..直接添加我们转化的bitmap就可以了.
IX.实现自定义覆盖物
首先我们需要定义一个xml文件布局..这个布局可以非常的复杂.但是这个布局的最外层布局只允许是LinearLayout..
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:background="@drawable/popup"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:scaleType="centerCrop"
android:padding="5dip"
android:src="@drawable/head_1"/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android :color/black"
android:textSize="20sp"
android:text="测试"/>
</LinearLayout>
然后我们把当前这个布局转化成Bitmap.然后在直接定义一个Marker对象.在内部添加Bitmap就可以了.转化成Bitmap的函数其实也并不是特别的复杂.之所以布局文件需要使用LinearLayout进行布局,而不能够使用RelativeLayout.是因为使用了makeMeasureSpec函数.这个函数貌似只对Linearayout有效.这样就可以将我们的xml文件布局转化成bitmap.转化完之后就可以进行添加了..
private Bitmap getViewBitmap(View addViewContent) { addViewContent.setDrawingCacheEnabled(true); addViewContent.measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
addViewContent.layout(0, 0,
addViewContent.getMeasuredWidth(),
addViewContent.getMeasuredHeight()); addViewContent.buildDrawingCache();
Bitmap cacheBitmap = addViewContent.getDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap); return bitmap;
}
说了这么多仅仅是完成了覆盖物的添加,那么如何定位还是一回事..如何根据我们的地理坐标实现定位呢?或者是根据我们的位置获取到地理坐标呢?这就需要使用到地理编码和反地理编码..
地理编码:将我们当前的地理信息转化成相应的位置.
反地理编码:将我们当前的坐标转化成地理信息.(注:反地理编码需要在网络链接状态的良好的情况下,才能够实现)
那么如何去实现呢?其实非常的简单..这个函数就实现了地理信息的编码和反编码.
private void reverseGeoCode(LatLng latLng){
//创建地理编码检索实例
GeoCoder geoCoder = GeoCoder.newInstance();
//设置地理编码的监听.
OnGetGeoCoderResultListener listener = new OnGetGeoCoderResultListener() {
//反地理编码函数的返回结果
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult arg0) {
// TODO Auto-generated method stub
if(arg0 == null || arg0.error != SearchResult.ERRORNO.NO_ERROR){
Toast.makeText(getApplicationContext(), "没有查找到结果", Toast.LENGTH_SHORT).show();
}
Toast.makeText(getApplicationContext(), "位置:"+arg0.getAddress(), Toast.LENGTH_SHORT).show();
}
//地理编码的返回结果
@Override
public void onGetGeoCodeResult(GeoCodeResult arg0) {
// TODO Auto-generated method stub
if(arg0 == null || arg0.error != SearchResult.ERRORNO.NO_ERROR){
Toast.makeText(getApplicationContext(), "没有查找到结果", Toast.LENGTH_SHORT).show();
}
}
};
//设置地理编码检索监听
geoCoder.setOnGetGeoCodeResultListener(listener);
//反地理编码需要传递坐标点参数.
geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(latLng));
}
地理编码和反地理编码都算是很好理解..通过使用API提供的接口.我们就可以轻松实现..通过创建地理编码检索对象,然后为对象设置相关的监听就可以了.地理编码和反地理编码仅仅能够确定我们的位置..但是如果想真正完成定位需要使用到定位的核心类.LocationClient.
X.LocationClient.
LocationClient是实现定位的核心类.定位服务的客户端.
locClient = new LocationClient(this);
locClient.registerLocationListener(locListener);
//定位模式 对象实例化
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); // 打开GPS
option.setCoorType("bd09ll");// 设置坐标类型
option.setAddrType("all"); // 地理信息设置
option.setScanSpan(1000); // 设置扫描间隔 locClient.setLocOption(option); //添加定位模式
locClient.start(); //启动定位
只有实例化了LocationClient对象.我们才能够真正的实现定位.实例化对象后.我们需要设置定位的监听.
定位监听的设置:
BDLocationListener locListener = new BDLocationListener() { @Override
public void onReceivePoi(BDLocation location) { }
//定位请求回调函数
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null || bdMap == null) {
return;
}
// 构造定位数据
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())//
.direction(100)// 方向
.latitude(location.getLatitude())//
.longitude(location.getLongitude())//
.build();
// 设置定位数据
bdMap.setMyLocationData(locData);
latitude = location.getLatitude();
longitude = location.getLongitude();
// 第一次定位的时候,那地图中心点显示为定位到的位置
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(),
location.getLongitude());
// MapStatusUpdate描述地图将要发生的变化
// MapStatusUpdateFactory生成地图将要反生的变化
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(ll);
bdMap.animateMapStatus(msu);
// bdMap.setMyLocationEnabled(false);
Toast.makeText(getApplicationContext(), location.getAddrStr(),
Toast.LENGTH_SHORT).show();
}
}
};
添加了定位的监听以及定位时需要的相关配置参数.就可以真正的实现定位了..
最后附上一个源代码:
http://files.cnblogs.com/files/RGogoing/Map.rar
Android学习笔记之使用LBS实现定位的更多相关文章
- Android 学习笔记之Volley(七)实现Json数据加载和解析...
学习内容: 1.使用Volley实现异步加载Json数据... Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- android学习笔记36——使用原始XML文件
XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- udacity android 学习笔记: lesson 4 part b
udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...
- Android学习笔记36:使用SQLite方式存储数据
在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...
- Android学习笔记之Activity详解
1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...
- Pro Android学习笔记 ActionBar(1):Home图标区
Pro Android学习笔记(四八):ActionBar(1):Home图标区 2013年03月10日 ⁄ 综合 ⁄ 共 3256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 ActionBar在A ...
- 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...
随机推荐
- HBase + Kerberos 配置示例(二)
接上篇<HBase + Kerberos配置示例(一)>,我们继续剩下的配置工作. 环境准备 Hadoop配置 Zookeeper配置 HBase配置 Java测试程序 环境准备 安装ha ...
- nginx+tomcat+java部署总结
昨天部署了一下nginx+tomcat+java出现了很多问题,以下为整理总结. 使用了两种部署方式,一种是源码部署,一种是war部署. java源码部署总结: 环境:nginx+tomcat 部署方 ...
- 进入做Mvc项目的时候 返现某个文件夹下面css js png等静态文件都访问不了
原来是我在该文件夹下面添加了一个web.config 里面 静止了所有的文件 直接访问 <system.web> <httpHandlers> <add ...
- Android 5.1 AOSP 源码获取
本文已同步更新至:http://dxjia.cn/2015/08/android-aosp-code-sync/ Android 5.1源码开放有一个多月啦,但由于城墙的关系,每次想着更新最新源码学习 ...
- Navi.Soft30.产品.阅读导航
Navi.Soft30.Core类库.开发手册 Navi.Soft30.框架.WinForm开发手册 Navi.Soft30.框架.WebMVC开发手册 Navi.Soft30.框架.Mobile.开 ...
- 记录javascript 验证字符串布尔类型 及url 参数获取
/^true$/i.test("false");false/^true$/i.test("true");true //获取请求参数的值 function Req ...
- Ajax学习笔记(二)
二.prototype库具体解释 1.prototype库的使用 //导入下载好的prototype.js文件 <script type="text/javascript" ...
- VARCHAR 详解
varchar(20):20指的是表中的a字段能存储的最大字符个数 In contrast to CHAR, VARCHAR values are stored as a 1-byte or 2-by ...
- Ajax实现提交表单时验证码自动验证(原创自Zjmainstay)
本文通过源码展示如何实现表单提交前,验证码先检测正确性,不正确则不提交表单,更新验证码. 1.前端代码 index.html <!DOCTYPE html> <html> &l ...
- Science上发表的超赞聚类算法
本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ 作者(Alex Rodriguez, Alessandro Laio)提出了一种很简洁优美的聚 ...