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

本以为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号和大体定位时间到[email protected],会有人追查原因");
            } 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....查了下官方文档,162167是服务端定位失败,这个原因是什么鬼,只好再次百度加谷歌了,然后得到的解决方案是在工程目录下的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的第一篇文章吧~

猜你喜欢

转载自blog.csdn.net/qj1943/article/details/49160445