您的位置:首页 > 移动开发 > Android开发

Android 百度定位SDK配置和实现当前位置定位

2015-02-07 10:43 477 查看
因为毕设要做到对当前位置实时定位,并计算距离附近的自动售货机的实时位置,因为主要是在大陆地区,所以研究了Android 百度定位SDK

定位SDK会根据设备当前的实际情况(如是否开启GPS,是否连接网络,是否扫描到Wi-Fi信息等)生成定位依据,并根据开发者设置的实际定位策略(包括三种:高精度模式,低功耗模式,仅用设备模式)进行定位。

NOTICE: 百度现在把地图SDK和定位SDK分开,如只需要实现定位功能,不需要使用地图SDK

关于百度SDK更详细的定位原理可以参考百度的文档:http://developer.baidu.com/map/geosdk.htm

步骤:

注册百度账号成为开发者后,去http://developer.baidu.com/map/geosdk.htm页面,左下角“相关下载”下载版本,本文采用Android定位SDKv4.1(这里吐槽一句,新版本还存在很多问题,官方提供的demo也有很多bug,程序无法定位,一直显示error code:602)
点击获取秘钥,根据网页提示获取属于你当前应用的访问应用(ak)
在下载的库文件中,将liblocSDK4.so文件拷贝到libs/armeabi目录下。将locSDK4.1.jar文件拷贝到工程的libs目录下,并在工程属性->Java Build Path->Libraries中选择“Add JARs”,选定locSDK4.1.jar,确定后返回。这样您就可以在程序中使用百度地理围栏SDK了。
设置AndroidManifest.xml

在Application标签中声明service组件,每个app拥有自己单独的定位service

1
2
3
4
5
6
7
8
9

<service

android:name="com.baidu.location.f"
android:enabled="true"

android:process=":remote" >
</service>


<meta-data

android:name="com.baidu.lbsapi.API_KEY"
android:value="填写访问应用(ak)"
/>

声明使用权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

<!-- 这个权限用于进行网络定位 -->

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
</uses-permission>

<!-- 这个权限用于访问GPS定位 -->
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" >

</uses-permission>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
</uses-permission>

<!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" >

</uses-permission>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
</uses-permission>

<!-- 用于读取手机当前的状态 -->
<uses-permission
android:name="android.permission.READ_PHONE_STATE" >

</uses-permission>
<!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
</uses-permission>

<!-- 访问网络,网络定位需要上网 -->
<uses-permission
android:name="android.permission.INTERNET" />

<!-- SD卡读取权限,用户写入离线定位数据 -->
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >

</uses-permission>
<!-- 允许应用读取低级别的系统日志文件 -->

<uses-permission android:name="android.permission.READ_LOGS" >
</uses-permission>

配置完后,既可以在MainActivity.java中写代码,代码如下:

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

package
com.example.baidudistancedemo;


import
android.app.Activity;

import android.os.Bundle;
import
android.util.Log;

import android.view.View;
import
android.view.View.OnClickListener;

import android.widget.Button;
import
android.widget.TextView;


import
com.baidu.location.BDLocation;

import com.baidu.location.BDLocationListener;
import
com.baidu.location.LocationClient;

import com.baidu.location.LocationClientOption;


/**
* 百度基站定位错误返回码

*/
// 61 : GPS定位结果

// 62 : 扫描整合定位依据失败。此时定位结果无效。
// 63 : 网络异常,没有成功向服务器发起请求。此时定位结果无效。

// 65 : 定位缓存的结果。
// 66 : 离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果

// 67 : 离线定位失败。通过requestOfflineLocaiton调用时对应的返回结果
// 68 : 网络连接失败时,查找本地离线定位时对应的返回结果

// 161: 表示网络定位结果
// 162~167: 服务端定位失败

// 502:KEY参数错误
// 505:KEY不存在或者非法

// 601:KEY服务被开发者自己禁用
// 602: KEY Mcode不匹配,意思就是您的ak配置过程中安全码设置有问题,请确保: sha1正确,“;”分号是英文状态;且包名是您当前运行应用的包名

// 501-700:KEY验证失败


public class
MainActivity extends
Activity implements
OnClickListener
{


public
LocationClient mLocationClient
= null;
public
BDLocationListener myListener
= new
MyLocationListener();


private
static final
String TAG
= "MainActivity";

private
TextView mText,
mTextPoi;


@Override
protected
void onCreate(Bundle
savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mLocationClient
= new
LocationClient(getApplicationContext());
// 声明LocationClient类
mLocationClient.setAccessKey("uof5MdWhsBtieU4OvMhXQGTm");

mLocationClient.registerLocationListener(myListener);
// 注册监听函数


setLocationOption();

mLocationClient.start();//
开始定位

initWidgets();
}


@Override

protected
void onDestroy()
{
// TODO Auto-generated method stub

super.onDestroy();
mLocationClient.stop();//
停止定位

}


private
void initWidgets()
{
mText
= (TextView)
findViewById(R.id.tv_text);

mTextPoi
= (TextView)
findViewById(R.id.tv_text_poi);
Button
btn =
(Button)
findViewById(R.id.btn_request);

btn.setOnClickListener(this);
btn
= (Button)
findViewById(R.id.btn_request_poi);

btn.setOnClickListener(this);
}


/**

* 设置相关参数
*/

private
void setLocationOption()
{
LocationClientOption
option =
new LocationClientOption();

option.setOpenGps(true);
option.setIsNeedAddress(true);
// 返回的定位结果包含地址信息

option.setAddrType("all");
// 返回的定位结果包含地址信息
option.setCoorType("bd09ll");
// 返回的定位结果是百度经纬度,默认值gcj02

option.setScanSpan(5000);
// 设置发起定位请求的间隔时间为5000ms
option.disableCache(true);
// 禁止启用缓存定位

option.setPoiNumber(5);
// 最多返回POI个数
option.setPoiDistance(1000);
// poi查询距离

option.setPoiExtraInfo(true);
// 是否需要POI的电话和地址等详细信息
mLocationClient.setLocOption(option);

}


public
class MyLocationListener
implements BDLocationListener
{
@Override

public
void onReceiveLocation(BDLocation
location)
{
if
(location
== null)

return;
StringBuffer
sb =
new StringBuffer(256);

sb.append("time : ");
sb.append(location.getTime());

sb.append("\nerror code : ");
sb.append(location.getLocType());

sb.append("\nlatitude : ");
sb.append(location.getLatitude());

sb.append("\nlontitude : ");
sb.append(location.getLongitude());

sb.append("\nradius : ");
sb.append(location.getRadius());

if
(location.getLocType()
== BDLocation.TypeGpsLocation)
{
sb.append("\nspeed
: ");

sb.append(location.getSpeed());
sb.append("\nsatellite
: ");

sb.append(location.getSatelliteNumber());
}
else if
(location.getLocType()
== BDLocation.TypeNetWorkLocation)
{

sb.append("\naddr : ");
sb.append(location.getAddrStr());

}
mText.setText(sb.toString());

Log.d(TAG,
"onReceiveLocation "
+ sb.toString());
}


public
void onReceivePoi(BDLocation
poiLocation)
{

// 将在下个版本中去除poi功能
if
(poiLocation
== null)
{

return;
}

StringBuffer sb
= new
StringBuffer(256);
sb.append("Poi time
: ");

sb.append(poiLocation.getTime());
sb.append("\nerror
code : ");

sb.append(poiLocation.getLocType());
sb.append("\nlatitude
: ");

sb.append(poiLocation.getLatitude());
sb.append("\nlontitude
: ");

sb.append(poiLocation.getLongitude());
sb.append("\nradius
: ");

sb.append(poiLocation.getRadius());
if
(poiLocation.getLocType()
== BDLocation.TypeNetWorkLocation)
{

sb.append("\naddr : ");
sb.append(poiLocation.getAddrStr());

}
if
(poiLocation.hasPoi())
{

sb.append("\nPoi:");
sb.append(poiLocation.getPoi());

}
else {
sb.append("noPoi information");

}
mTextPoi.setText(sb.toString());

Log.d(TAG,
"onReceiveLocation "
+ sb.toString());
}

}


@Override
public
void onClick(View
v)
{

// TODO Auto-generated method stub
switch
(v.getId())
{

case
R.id.btn_request:
if
(mLocationClient
!= null
&& mLocationClient.isStarted())

mLocationClient.requestLocation();
else

Log.d(TAG,
"locClient is null or not started");
break;

case
R.id.btn_request_poi:
// 请求POI数据

if
(mLocationClient
!= null
&& mLocationClient.isStarted())
mLocationClient.requestPoi();

break;
default:

break;
}

}
}

代码说明:

1. 虽然在AndroidManifest.xml里面添加了AK,但是在程序运行中仍然会出现问题,所以在代码中也添加一行

1

mLocationClient.setAccessKey("uof5MdWhsBtieU4OvMhXQGTm");

2. 官方文档给的demo中,onCreate缺少start(),需要补充,具体见53行高亮代码:

1

mLocationClient.start();//
开始定位

3. 写到这里的时候运行程序,既可以得到你当前的地址,经纬度等其他信息,定位的效果如下:



也可以单独获取省市信息:

1
2
3
4
5
6
7
8
9
10
11
12

sb.append("\n省份 : ");

sb.append(location.getProvince());
sb.append("\n城市 : ");

sb.append(location.getCity());
sb.append("\n区/县 : ");

sb.append(location.getDistrict());
sb.append("\n街道: ");

sb.append(location.getStreet());
sb.append("\n街道号码: ");

sb.append(location.getStreetNumber());
sb.append("\n地址 : ");

sb.append(location.getAddrStr());

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: