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

android 百度地图定位SDK使用方法

2015-10-15 23:11 441 查看
本以为gps定位就只是拿个经纬度,不会很复杂,结果折腾了一下午才弄好,惭愧啊~

Ps:今天练跆拳道,刚热身就两条腿一起抽筋,难道是平时撸多了......好吧,我想多了,废话不多说,开始入正题~

首先介绍一般的拿法:

private void getLocation(){// 获取位置管理服务LocationManager locationManager;String serviceName = Context.LOCATION_SERVICE;locationManager = (LocationManager) this.getSystemService(serviceName);// 查找到服务信息Criteria criteria = new Criteria();criteria.setAccuracy(Criteria.ACCURACY_FINE); // 高精度criteria.setAltitudeRequired(false);criteria.setBearingRequired(false);criteria.setCostAllowed(true);criteria.setPowerRequirement(Criteria.POWER_LOW); // 低功耗 String provider = locationManager.getBestProvider(criteria, true); // 获取GPS信息Location location = locationManager.getLastKnownLocation(provider); // 通过GPS获取位置updateToNewLocation(location);// 设置监听器,自动更新的最小时间为间隔N秒(1秒为1*1000,这样写主要为了方便)或最小位移变化超过N米locationManager.requestLocationUpdates(provider, 100 * 1000, 500,locationListener);}


结果发现location死活拿不到,始终是null,然后满世界搜索如何解决location未null的问题,结果给我找到了下面这篇文章:

http://www.tuicool.com/articles/yINfaa

好了,看完他的分析我也就死心了,大意是真机在室内gps模块基本无用,而通过网络wifi、3g的方式拿gps又需要google的服务器提供服务,而总所周知,寡妇王的存在,极大的阻碍了科技进步,社会和谐,人类发展.....(我错了,警察蜀黍不要请我喝茶),所以,坐在室内开发的猿,用这种方法是拿不到gps的,好在这篇文章在后面介绍了百度地图提供了api可以定位,好了,果断去百度找百度要百度地图定位使用方法(好绕啊- -!)

首先,从百度开发者官网上下了个demo,测试了下下,挺好用的,然后开始嵌入到自己的工程中,步骤如下:

0、首先将百度提供的demo里面的libs下的locSDK_6.03.jar和armeabi下的liblocSDK6.so拷贝到自己工程对应的文件夹下。

1、查官方文档(http://developer.baidu.com/map/index.php?title=android-locsdk/qa)可知

定位SDK的调用必须在主线程中,所以例子中子类化了application类,并在其中为LocationClient设置回调函数用于拿定位的信息:

public class MyApplication extends Application {
private static Context context;
public LocationClient mLocationClient;
public MyLocationListener mMyLocationListener;
public static MLocation  mBaseLocation;

public class MLocation {
public double latitude;
public double longitude;
}

@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
mBaseLocation = new MLocation();

mLocationClient = new LocationClient(this.getApplicationContext());
mMyLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(mMyLocationListener);
}

public static Context getContext(){
return context;
}

/**
* 实现实时位置回调监听
*/
public class MyLocationListener implements BDLocationListener {

@Override
public void onReceiveLocation(BDLocation location) {
//Receive Location

mBaseLocation.latitude = location.getLatitude();
mBaseLocation.longitude = location.getLongitude();

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("网络定位成功");
} 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 : ");// 位置语义化信息
sb.append(location.getLocationDescribe());

Log.i("BaiduLocationApiDem", sb.toString());
}
}
}


2、在mainacitivity中初始化下:

public class MainActivity extends ActionBarActivity {

private LocationClient mLocationClient;
private LocationMode tempMode = LocationMode.Hight_Accuracy;
private String tempcoor="gcj02";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocationClient = ((MyApplication)getApplication()).mLocationClient;
initLocation();
mLocationClient.start();
}


3、所需权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.easyrat"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_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="MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" android:debuggable="true">
<activity
android:name=".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>

<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
android:name="com.baidu.lbsapi.API_KEY"
android:value="这里写你从百度申请的ak密钥" />
</application>
</manifest>


好了,至此拿gps代码就算搞定了,理论上应该可以了吧,是的,又出现了新问题,只适合你会发现log里面一直在报错误码为162....查了下官方文档,162—167是服务端定位失败,这个原因是什么鬼,只好再次百度加谷歌了,然后得到的解决方案是在工程目录下的libs/armeabi下必须包含liblocSDK6.so,是啊,第一步我就加了啊,难不成apk没有打包进去,嗯,用rar查看了下apk,嗯,果然没有了,但是我明明添加过了啊啊 ~~~

好吧,我再添加一次,再次编译,还是没有打包进apk。这里,出现这个问题的原因竟然是ndk-build下编译后,libs/armeabi文件夹会自动更新,然后第三方so库文件就被删除了,网上看到一个人说自己把这个文件独占方式打开,然后看ecplipse怎么删,我对这种思路真是膜拜到五体投地.....

然后,经过百度(好吧,我承认离开了百度,我一行代码也写不出来- -!),然后我找到了这位同学也在积极提问的帖子:http://bbs.csdn.net/topics/390397961,需要通过prebuild的方式,编写android.mk将第三方库文件包含进来,方法如下:

1、在jni目录下新目录prebuilt,在此目录下新文件Androidusc.mk(名字随便取),将第三方库.so复制到此目录

2、打开Androidusc.mk添加内容,例如第三方库是libScreenPop.so:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := ScreenPop

LOCAL_SRC_FILES := libScreenPop.so

include $(PREBUILT_SHARED_LIBRARY)

3、修改jni目录下的Android.mk文件,加入一条语句:

include $(LOCAL_PATH)/prebuilt/Androidusc.mk

结果还是不行,最后还是看了3楼的解答才最终成功解决问题,直接在唯一的android.mk中最开始添加下面的代码:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := locSDK6

LOCAL_SRC_FILES := prebuilt/liblocSDK6.so

include $(PREBUILT_SHARED_LIBRARY)

好了,这时,才最终大功告成了,回头看看,不就是个gps嘛,真费劲- -!,还是基本功不扎实啊,走了好多坑,写此文记之,也是我的blog的第一篇文章吧~。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: