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

Android 百度地图定位功能

2016-05-13 10:31 435 查看
定位原理

使用百度Android定位SDK必须注册GPS和网络使用权限。定位SDK采用GPS、基站、Wi-Fi信号进行定位。当应用程序向定位SDK发起定位请求时,定位SDK会根据应用的定位因素(GPS、基站、Wi-Fi信号)的实际情况(如是否开启GPS、是否连接网络、是否有信号等)来生成相应定位依据进行定位。

用户可以设置满足自身需求的定位依据:

若用户设置GPS优先,则优先使用GPS进行定位,如果GPS定位未打开或者没有可用位置信息,且网络连接正常,定位SDK则会返回网络定位(即Wi-Fi与基站)的最优结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。





定位精度



了解了百度定位的原理和定位精度之后,接下来我们就来使用百度定位SDKv4.0吧

一 . 导入库文件

在使用百度定位SDKv4.0之前,我们要下载最新的库文件,下载地址:百度地图Api中下载最新的JAR包和.SO文件库 并且到百度开放平台申请对应的Appk 然后在ManiFest清单文件中进行配置 相应的权限 和Appkey

    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />

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

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

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

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

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

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

    <!-- 这个权限用于进行网络定位-->
<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>

权限配置完成后 在Application节点中配置AppKey和服务

    <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="XOVv2B12hoyku9ZmsBFS2QGiAd4ZRfbb" />

二 . 布局文件,一个百度地图控件,加一个ListView列表展示附近的位置,放在一个线性布局里面,很简单的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    tools:context="com.itcast.cn.MainActivity" >

   <com.baidu.mapapi.map.MapView  

    android:id="@+id/bmapView"  

    android:layout_width="fill_parent"  

    android:layout_height="300dp"  

    android:clickable="true" />

   <TextView 

       android:id="@+id/tv_view"

       android:layout_width="fill_parent"

       android:layout_height="wrap_content"

       android:layout_marginTop="5dp"

       android:layout_marginBottom="5dp"

       android:layout_marginLeft="10dp"

       android:textColor="@android:color/black"

       android:visibility="gone"

       android:textSize="20sp"

       android:text="附近位置"/>

   <ListView

       android:id="@+id/list_view" 

       android:layout_width="fill_parent"

       android:layout_height="wrap_content"/>

</LinearLayout>

 三. 初始化百度地图Sdk我们一般会放到Application中去初始化
fefe

public class MyApplication extends Application {
public LocationClient mLocationClient = null;
@Override
public void onCreate() {
super.onCreate();
initBaiduMap(getApplicationContext());
}
public void initBaiduMap(Context context) {
SDKInitializer.initialize(context);
}

}

 四. 界面MainActivity代码,先贴上,然后适当讲解相关代码,我注释也比较清楚

import java.util.ArrayList;

import java.util.List;

import com.baidu.location.BDLocation;

import com.baidu.location.BDLocationListener;

import com.baidu.location.LocationClient;

import com.baidu.location.LocationClientOption;

import com.baidu.location.LocationClientOption.LocationMode;

import com.baidu.location.Poi;

import com.baidu.mapapi.map.BaiduMap;

import com.baidu.mapapi.map.BitmapDescriptor;

import com.baidu.mapapi.map.BitmapDescriptorFactory;

import com.baidu.mapapi.map.CircleOptions;

import com.baidu.mapapi.map.InfoWindow;

import com.baidu.mapapi.map.MapStatus;

import com.baidu.mapapi.map.MapStatusUpdateFactory;

import com.baidu.mapapi.map.MapView;

import com.baidu.mapapi.map.MarkerOptions;

import com.baidu.mapapi.map.OverlayOptions;

import com.baidu.mapapi.map.Stroke;

import com.baidu.mapapi.model.LatLng;

import android.support.v7.app.ActionBarActivity;

import android.util.Log;

import android.view.View;

import android.view.ViewGroup;

import android.view.Window;

import android.widget.BaseAdapter;

import android.widget.ListView;

import android.widget.TextView;

import android.content.Context;

import android.content.Intent;

import android.graphics.Color;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

public class MainActivity extends ActionBarActivity {
public static final int IS_DATA_RETUED = 0;
private MapView bmapView;
public LocationClient mLocationClient = null;
public BDLocationListener myListener = new MyLocationListener();
private BaiduMap mbaiduMap;
private TextView tv_view;
private ListView list_view;
private List<Poi> mlist;
private MyAdapter adapter;
private LatLng point;
private Handler handler = new Handler() {
@SuppressWarnings("unchecked")
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case IS_DATA_RETUED:
mlist = (List<Poi>) msg.obj;
if (mlist.size() > 0 && mlist != null) {
tv_view.setVisibility(View.VISIBLE);
adapter = new MyAdapter(mlist);
list_view.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mlist = new ArrayList<Poi>();
initMap();
}
private void initMap() {
bmapView = (MapView) findViewById(R.id.bmapView);
tv_view = (TextView) findViewById(R.id.tv_view);
list_view = (ListView) findViewById(R.id.list_view);
mbaiduMap = bmapView.getMap();
// 设置缩放级别
mbaiduMap.setMapStatus(MapStatusUpdateFactory
.newMapStatus(new MapStatus.Builder().zoom(15).build()));
// 开启交通图
mbaiduMap.setTrafficEnabled(true);
// 声明LocationClient类
mLocationClient = new LocationClient(getApplicationContext());
// 注册监听函数
mLocationClient.registerLocationListener(myListener);
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationMode.Hight_Accuracy);// 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setCoorType("bd09ll");// 可选,默认gcj02,设置返回的定位结果坐标系
option.setScanSpan(2000);// 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);// 可选,设置是否需要地址信息,默认不需要
option.setOpenGps(true);// 可选,默认false,设置是否使用gps
option.setLocationNotify(true);// 可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
option.setIsNeedLocationDescribe(true);// 可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationPoiList(true);// 可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
option.setIgnoreKillProcess(false);// 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
option.SetIgnoreCacheException(false);// 可选,默认false,设置是否收集CRASH信息,默认收集
option.setEnableSimulateGps(false);// 可选,默认false,设置是否需要过滤gps仿真结果,默认需要
mLocationClient.setLocOption(option);
mLocationClient.start();
}

@Override
protected void onDestroy() {
super.onDestroy();
// 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
bmapView.onDestroy();
}

@Override
protected void onResume() {
super.onResume();
// 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
bmapView.onResume();
}

@Override
protected void onPause() {
super.onPause();
// 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
bmapView.onPause();
}

public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
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) {// GPS定位结果
sb.append("\nspeed : ");
sb.append(location.getSpeed());// 单位:公里每小时
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber());
sb.append("\nheight : ");
sb.append(location.getAltitude());// 单位:米
sb.append("\ndirection : ");
sb.append(location.getDirection());// 单位度
sb.append("\naddr : ");
sb.append(location.getAddrStr());
sb.append("\ndescribe : ");
sb.append("gps定位成功");

} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
sb.append("\naddr : ");
sb.append(location.getAddrStr());
// 运营商信息
sb.append("\noperationers : ");
sb.append(location.getOperators());
sb.append("\ndescribe : ");
sb.append("网络定位成功");
}
sb.append("\nlocationdescribe : ");
sb.append(location.getLocationDescribe());// 位置语义化信息
List<Poi> list = location.getPoiList();// POI数据
if (list != null) {
mlist.clear();
mlist.addAll(list);
Message msg = Message.obtain();
msg.obj = mlist;
msg.what = IS_DATA_RETUED;
handler.sendMessage(msg);
sb.append("\npoilist size = : ");
sb.append(list.size());
for (Poi p : list) {
sb.append("\npoi= : ");
sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
}
}
Log.i("BaiduLocationApiDem", sb.toString());
point = new LatLng(location.getLatitude(), location.getLongitude());
// 构建Marker图标
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.loading_point_medium); // 推算结果
// 构建MarkerOption,用于在地图上添加Marker
OverlayOptions option = new MarkerOptions().position(point).icon(
bitmap);
// 首先清除图层 不然当位置改变的时候图层会叠加
mbaiduMap.clear();
mbaiduMap.addOverlay(option);
showPop(getApplicationContext(), location);
mbaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(point));
rycloCover();
}
}
private class MyAdapter extends BaseAdapter {
private List<Poi> mpList;

public MyAdapter(List<Poi> m) {
this.mpList = m;
}

@Override
public int getCount() {
return mpList.size();
}

@Override
public Object getItem(int arg0) {
return mpList.get(arg0);
}

@Override
public long getItemId(int arg0) {
return 0;
}

@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
final ViewdHolder holder;
if (arg1 == null) {
arg1 = getLayoutInflater().inflate(R.layout.activity_main_itme,
null);
holder = new ViewdHolder();
holder.te_text = (TextView) arg1.findViewById(R.id.te_text);
arg1.setTag(holder);
} else {
holder = (ViewdHolder) arg1.getTag();
}
holder.te_text.setText(mpList.get(arg0).getName());

return arg1;
}

private class ViewdHolder {
public TextView te_text;
}
}

/*******

* @param context
* @param location
*   设置百度地图弹窗层 的popWindon
*/

private void showPop(Context context, final BDLocation location) {
View view = View.inflate(context, R.layout.activity_main_pop, null);
TextView tv_adrss = (TextView) view.findViewById(R.id.tv_adrss);
tv_adrss.setText(location.getLocationDescribe());
tv_adrss.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, Wzg.class);
intent.putExtra("wwww", location.getLatitude());
intent.putExtra("wzg", location.getLongitude());
startActivity(intent);
}
});
LatLng latLng = new LatLng(location.getLatitude(),
location.getLongitude());
InfoWindow info = new InfoWindow(view, latLng, -15);
mbaiduMap.showInfoWindow(info);
}
/***
* 百度地图绘制圆形覆盖物
*/
private void rycloCover() {
// 设置边框的宽度 和颜色
Stroke st = new Stroke(2, Color.GRAY);
// 创建画圆的实体类
CircleOptions circleOptions = new CircleOptions();
circleOptions.stroke(st);
// 设置当前的经纬度坐标
circleOptions.center(point).radius(1000);
// Color.parseColor("#a0000000")
// 设置圆的内容填充色
circleOptions.fillColor(R.drawable.loading_point_medium);
// 添加到
mbaiduMap.addOverlay(circleOptions);
}

}

定位原理

使用百度Android定位SDK必须注册GPS和网络使用权限。定位SDK采用GPS、基站、Wi-Fi信号进行定位。当应用程序向定位SDK发起定位请求时,定位SDK会根据应用的定位因素(GPS、基站、Wi-Fi信号)的实际情况(如是否开启GPS、是否连接网络、是否有信号等)来生成相应定位依据进行定位。

用户可以设置满足自身需求的定位依据:

若用户设置GPS优先,则优先使用GPS进行定位,如果GPS定位未打开或者没有可用位置信息,且网络连接正常,定位SDK则会返回网络定位(即Wi-Fi与基站)的最优结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。





定位精度



了解了百度定位的原理和定位精度之后,接下来我们就来使用百度定位SDKv4.0吧

一 . 导入库文件

在使用百度定位SDKv4.0之前,我们要下载最新的库文件,下载地址:点击下载相关库文件,将liblocSDK4.so文件拷贝到libs/armeabi目录下。将locSDK4.0.jar文件拷贝到工程的libs目录下
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: