因为项目需求,需要使用百度地图的定位功能,因此去百度地图开发平台下载了百度地图的Android定位SDK最新版本的开发包和示例代码学习。
Android 定位SDK地址:http://developer.baidu.com/map/index.php?title=android-locsdk
下载地址为:http://developer.baidu.com/map/index.php?title=android-locsdk/geosdk-android-download
下载示例代码后,导入到相应的IDE工具。代码有android_studio和eclipse两个版本。我使用的Eclipse,因此导入Eclipse的版本代码。
先申请秘钥,然后修改AndroidManifest.xml中的代码,具体要修改的代码如下:
<!-- meta-data需要写在application中 --> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="请输入AK" />
具体的秘钥申请步骤,请参考链接:http://developer.baidu.com/map/index.php?title=android-locsdk/guide/key
如果上面的key值不对或者是没有的话,运行项目会出现下面的结果,其中的error code:505代表key不存在或者非法。
完成上述步骤后,就可以运行该项目了。正常运行项目后,如下所示:
====================================================================================
下面来具体看看项目代码,项目的结构如下图所示,开发所需要的SDK是最新版本的locSDK_6.11.jar,还有liblocSDK6a.so库文件
主要的类有三个,LocationActivity、NotifyActivity和LocationApplication。
LocationActivity.java主要功能是展示定位的信息,代码如下:
package com.baidu.baidulocationdemo; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.location.LocationClientOption.LocationMode; import android.app.Activity; import android.os.Bundle; import android.text.method.ScrollingMovementMethod; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TextView; public class LocationActivity extends Activity{ private LocationClient mLocationClient; private TextView LocationResult,ModeInfor; private Button startLocation; private RadioGroup selectMode,selectCoordinates; private EditText frequence; private LocationMode tempMode = LocationMode.Hight_Accuracy; private String tempcoor="gcj02"; private CheckBox checkGeoLocation; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.location); mLocationClient = ((LocationApplication)getApplication()).mLocationClient; LocationResult = (TextView)findViewById(R.id.textView1); LocationResult.setMovementMethod(ScrollingMovementMethod.getInstance()); ModeInfor= (TextView)findViewById(R.id.modeinfor); ModeInfor.setText(getString(R.string.hight_accuracy_desc)); ((LocationApplication)getApplication()).mLocationResult = LocationResult; frequence = (EditText)findViewById(R.id.frequence); checkGeoLocation = (CheckBox)findViewById(R.id.geolocation); startLocation = (Button)findViewById(R.id.addfence); startLocation.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //初始化定位SDK的配置参数 initLocation(); if(startLocation.getText().equals(getString(R.string.startlocation))){ //启动定位sdk mLocationClient.start();//定位SDK start之后会默认发起一次定位请求,开发者无须判断isstart并主动调用request startLocation.setText(getString(R.string.stoplocation)); }else{ //停止定位sdk mLocationClient.stop(); startLocation.setText(getString(R.string.startlocation)); } } }); selectMode = (RadioGroup)findViewById(R.id.selectMode); selectCoordinates= (RadioGroup)findViewById(R.id.selectCoordinates); selectMode.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { String ModeInformation = null; switch (checkedId) { case R.id.radio_hight: //高精度定位模式:这种定位模式下,会同时使用网络定位和GPS定位,优先返回最高精度的定位结果; tempMode = LocationMode.Hight_Accuracy;//高精度模式 ModeInformation = getString(R.string.hight_accuracy_desc); break; case R.id.radio_low: //低功耗定位模式:这种定位模式下,不会使用GPS,只会使用网络定位(Wi-Fi和基站定位) tempMode = LocationMode.Battery_Saving;//低功耗模式 ModeInformation = getString(R.string.saving_battery_desc); break; case R.id.radio_device: //仅用设备定位模式:这种定位模式下,不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位 tempMode = LocationMode.Device_Sensors;//仅设备(Gps)模式 ModeInformation = getString(R.string.device_sensor_desc); break; default: break; } ModeInfor.setText(ModeInformation); } }); selectCoordinates.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { // TODO Auto-generated method stub switch (checkedId) { case R.id.radio_gcj02: tempcoor="gcj02";//国家测绘局标准 break; case R.id.radio_bd09ll: tempcoor="bd09ll";//百度经纬度标准 break; case R.id.radio_bd09: tempcoor="bd09";//百度墨卡托标准 break; default: break; } } }); } @Override protected void onStop() { //停止定位sdk mLocationClient.stop(); super.onStop(); } /** * 初始化定位SDK的配置参数 */ private void initLocation(){ //配置定位SDK各配置参数,比如定位模式、定位时间间隔、坐标系类型等 LocationClientOption option = new LocationClientOption(); //设置定位模式:高精度,低功耗,仅设备 option.setLocationMode(tempMode); /* * 设置坐标类型 * coorType - 取值有3个: * 返回国测局经纬度坐标系:gcj02 * 返回百度墨卡托坐标系 :bd09 * 返回百度经纬度坐标系 :bd09ll */ option.setCoorType(tempcoor); int span=1000; try { span = Integer.valueOf(frequence.getText().toString()); } catch (Exception e) { // TODO: handle exception } /* * 设置扫描间隔,单位是毫秒 当<1000(1s)时,定时定位无效 * 默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的 */ option.setScanSpan(span); //设置是否需要地址信息,默认为无地址 option.setIsNeedAddress(checkGeoLocation.isChecked()); //设置是否打开gps进行定位 option.setOpenGps(true); //可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果 option.setLocationNotify(true); /* * 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程, * 设置是否在stop的时候杀死这个进程,默认不杀死 */ option.setIgnoreKillProcess(true); //可选,默认false,设置是否需要过滤gps仿真结果,默认需要 option.setEnableSimulateGps(false); /* * 可选,默认false,设置是否需要位置语义化结果, * 可以在BDLocation.getLocationDescribe里得到, * 结果类似于“在北京*附近” */ option.setIsNeedLocationDescribe(true); /* * 设置是否需要返回位置POI信息,可以在BDLocation.getPoiList()中得到数据 */ option.setIsNeedLocationPoiList(true); mLocationClient.setLocOption(option); } }
该acvtivity的布局文件为location.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="200dp" android:layout_weight="2.89" android:maxLines="12" android:scrollbars="vertical" android:text=" " android:textColor="#ffffffff" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" 定位模式" android:textAppearance="?android:attr/textAppearanceLarge" /> <RadioGroup android:id="@+id/selectMode" android:layout_width="wrap_content" android:layout_height="match_parent" > <RadioButton android:id="@+id/radio_hight" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="高精度" /> <RadioButton android:id="@+id/radio_low" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="低功耗" /> <RadioButton android:id="@+id/radio_device" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="仅设备" /> </RadioGroup> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="坐标系" android:textAppearance="?android:attr/textAppearanceLarge" /> <RadioGroup android:id="@+id/selectCoordinates" android:layout_width="wrap_content" android:layout_height="match_parent" > <RadioButton android:id="@+id/radio_gcj02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="gcj02(国测局加密经纬度坐标)" /> <RadioButton android:id="@+id/radio_bd09ll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="bd09ll(百度加密经纬度坐标)" /> <RadioButton android:id="@+id/radio_bd09" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="bd09(百度加密墨卡托坐标)" /> </RadioGroup> </LinearLayout> </LinearLayout> <TextView android:id="@+id/modeinfor" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2.88" android:text=" " /> <LinearLayout android:layout_width="278dp" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="定位时间间隔(ms):" android:textAppearance="?android:attr/textAppearanceLarge" /> <EditText android:id="@+id/frequence" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="1000" android:inputType="number" > <requestFocus /> </EditText> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2.89" android:orientation="horizontal" > <TextView android:id="@+id/geofencelog" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="反地理编码" android:textAppearance="?android:attr/textAppearanceLarge" /> <CheckBox android:id="@+id/geolocation" android:layout_width="match_parent" android:layout_height="wrap_content" android:text=" " /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2.89" android:gravity="center|top" android:orientation="vertical" > <Button android:id="@+id/addfence" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开启定位" /> </LinearLayout> </LinearLayout>
在LocationActivity中引用的LocationApplication,主要功能是定位功能的主要逻辑都在这里,代码如下:
package com.baidu.baidulocationdemo; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.Poi; import android.app.Application; import android.app.Service; import android.os.Vibrator; import android.util.Log; import android.widget.TextView; import java.util.List; /** * 主Application,所有百度定位SDK的接口说明请参考线上文档:http://developer.baidu.com/map/loc_refer/index.html * 百度定位SDK官方网站:http://developer.baidu.com/map/index.php?title=android-locsdk */ public class LocationApplication extends Application { public LocationClient mLocationClient; public MyLocationListener mMyLocationListener; public TextView mLocationResult,logMsg; public TextView trigger,exit; public Vibrator mVibrator; @Override public void onCreate() { super.onCreate(); mLocationClient = new LocationClient(this.getApplicationContext()); mMyLocationListener = new MyLocationListener(); mLocationClient.registerLocationListener(mMyLocationListener); mVibrator =(Vibrator)getApplicationContext().getSystemService(Service.VIBRATOR_SERVICE); } /** * 实现实时位置回调监听 */ public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { //Receive Location StringBuffer sb = new StringBuffer(256); sb.append("time : "); //server返回的当前定位时间 sb.append(location.getTime()); sb.append("\nerror code : "); /* * 获取定位类型 * 常量字段 值 描述 * TypeCacheLocation 65 定位结果描述:缓存定位结果 TypeCriteriaException 62 定位结果描述:无法定位结果 TypeGpsLocation 61 定位结果描述:GPS定位结果 TypeNetWorkException 63 定位结果描述:网络连接失败 TypeNetWorkLocation 161 定位结果描述:网络定位结果 TypeNone 0 定位结果描述:无效定位结果 TypeOffLineLocation 66 定位结果描述:离线定位成功结果 TypeOffLineLocationFail 67 定位结果描述:离线定位失败结果 TypeOffLineLocationNetworkFail 68 定位结果描述:网络连接失败时,查找本地离线定位时对应的返回结果 TypeServerError 167 定位结果描述:server定位失败 */ sb.append(location.getLocType()); sb.append("\nlatitude : "); //获取纬度坐标 sb.append(location.getLatitude()); sb.append("\nlontitude : "); //获取经度坐标 sb.append(location.getLongitude()); sb.append("\nradius : "); //获取定位精度,默认值0.0f sb.append(location.getRadius()); if (location.getLocType() == BDLocation.TypeGpsLocation){// GPS定位结果 sb.append("\nspeed : "); //获取速度,仅gps定位结果时有速度信息,单位公里/小时,默认值0.0f sb.append(location.getSpeed());// 单位:公里每小时 sb.append("\nsatellite : "); //gps定位结果时,获取gps锁定用的卫星数 sb.append(location.getSatelliteNumber()); sb.append("\nheight : "); //获取高度信息,目前只有是GPS定位结果时才有效,单位米 sb.append(location.getAltitude());// 单位:米 sb.append("\ndirection : "); //gps定位结果时,行进的方向,单位度 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 : "); /* * 获取运营商信息 * 常量字段 描述 值 * OPERATORS_TYPE_UNKONW 未知运营商 0 * OPERATORS_TYPE_MOBILE 中国移动 1 * OPERATORS_TYPE_UNICOM 中国联通 2 * OPERATORS_TYPE_TELECOMU 中国电信 3 */ sb.append(location.getOperators()); sb.append("\ndescribe : "); sb.append("网络定位成功"); } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果 sb.append("\ndescribe : "); sb.append("离线定位成功,离线定位结果也是有效的"); } else if (location.getLocType() == BDLocation.TypeServerError) { sb.append("\ndescribe : "); sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因"); } else if (location.getLocType() == BDLocation.TypeNetWorkException) { sb.append("\ndescribe : "); sb.append("网络不同导致定位失败,请检查网络是否通畅"); } else if (location.getLocType() == BDLocation.TypeCriteriaException) { sb.append("\ndescribe : "); sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机"); } sb.append("\nlocationdescribe : ");// 位置语义化信息 //获取位置语义化信息,没有的话返回NULL sb.append(location.getLocationDescribe()); //仅在开发者设置需要POI信息时才会返回,在网络不通或无法获取时有可能返回null List<Poi> list = location.getPoiList();// POI信息 if (list != null) { sb.append("\npoilist size = : "); sb.append(list.size()); /** * POI: POI封装类,可以得到POI的ID、NAME、RANK(概率)值 * poi字串JSON格式的字符串。 * getId(): 获取POI的ID字符串 * getName(): 获取POI的名字字符串 * getRank(): 获取POI概率值,表示该POI在当前位置周边的概率 */ for (Poi p : list) { sb.append("\npoi= : "); sb.append(p.getId() + " " + p.getName() + " " + p.getRank()); } } logMsg(sb.toString()); Log.i("BaiduLocationApiDem", sb.toString()); } } /** * 显示请求字符串 * @param str */ public void logMsg(String str) { try { if (mLocationResult != null) mLocationResult.setText(str); } catch (Exception e) { e.printStackTrace(); } } }
NotifyActivity.java的主要功能是位置提醒功能,代码如下
package com.baidu.baidulocationdemo; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.BDNotifyListener; import com.baidu.location.LocationClient; import android.app.Activity; import android.app.Service; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Vibrator; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class NotifyActivity extends Activity{ private Button startNotify; private Vibrator mVibrator; private LocationClient mLocationClient; private NotiftLocationListener listener; private double longtitude,latitude; private NotifyLister mNotifyLister; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.notify); listener = new NotiftLocationListener(); mVibrator =(Vibrator)getApplicationContext().getSystemService(Service.VIBRATOR_SERVICE); startNotify = (Button)findViewById(R.id.notifystart); mLocationClient = new LocationClient(this); mLocationClient.registerLocationListener(listener); startNotify.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(startNotify.getText().toString().equals("开启位置提醒")){ mLocationClient.start(); startNotify.setText("关闭位置提醒"); }else{ if(mNotifyLister!=null){ //取消注册的位置提醒监听 mLocationClient.removeNotifyEvent(mNotifyLister); startNotify.setText("开启位置提醒"); } } } }); } @Override protected void onStop() { super.onStop(); //取消注册的位置提醒监听 mLocationClient.removeNotifyEvent(mNotifyLister); mLocationClient = null; mNotifyLister= null; listener = null; } private Handler notifyHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); mNotifyLister = new NotifyLister(); /* * 设置位置提醒的点的相关参数,4个参数代表要位置提醒的点的坐标,具体含义依次为: * latitude - 纬度 longitude - 经度 radius - 距离范围 coorType - 坐标系类型(gcj02,gps,bd09,bd09ll) */ mNotifyLister.SetNotifyLocation(latitude,longtitude, 3000,"gcj02"); //注册位置提醒监听 mLocationClient.registerNotify(mNotifyLister); } }; public class NotiftLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { //Receive Location longtitude = location.getLongitude();//获取经度坐标 latitude = location.getLatitude(); //获取纬度坐标 notifyHandler.sendEmptyMessage(0); } } public class NotifyLister extends BDNotifyListener{ /* * 位置提醒回调函数 * mlocation: 位置坐标 * distance: 当前位置跟设定提醒点的距离 */ @Override public void onNotify(BDLocation mlocation, float distance){ mVibrator.vibrate(1000);//振动提醒已到设定位置附近 Toast.makeText(NotifyActivity.this, "震动提醒", Toast.LENGTH_SHORT).show(); } } }
描述文件AndroidManifest.xml代码如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.baidu.baidulocationdemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_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.INTERNET" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <application android:name="com.baidu.baidulocationdemo.LocationApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Black" > <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" > <intent-filter> <action android:name="com.baidu.location.service_v2.2" > </action> </intent-filter> </service> <!-- meta-data需要写在application中 --> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="这里填写你申请的百度 key" /> <activity android:name="com.baidu.baidulocationdemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.baidu.baidulocationdemo.LocationActivity" > </activity> <activity android:name="com.baidu.baidulocationdemo.NotifyActivity" > </activity> <activity android:name="com.baidu.baidulocationdemo.QuestActivity" > </activity> </application> </manifest>
====================================================================================
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
====================================================================================