項目最近要把定位服務獨立出來,所以順便把定位服務升級到4.2最新版。以下記錄一個簡單的定位服務的實現(基於百度Android定位4.2版本)
1:首先到百度LBS平台申請密鑰
申請密鑰需要安全碼:你的Eclipse SHA1指紋(Preferences->Android->Build)+分號+應用程序包名
例如:
FS:54:EB:47:23:F6:70:FD:DD:GF:53:FS:10:1F:1A:54:00:5E:C0:24;com.example.testandroid
2:下載並添加百度定位的jar、so文件
locSDK_4.2.jar添加到libs包下,另外,libs目錄下新建目錄armeabi,並把liblocSDK4d.so文件復制其中
3:配置AndroidManifest.xml文件
聲明使用權限
1 <!-- 這個權限用於進行網絡定位--> 2 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> 3 <!-- 這個權限用於訪問GPS定位--> 4 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> 5 <!-- 用於訪問wifi網絡信息,wifi信息會用於進行網絡定位--> 6 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> 7 <!-- 獲取運營商信息,用於支持提供運營商信息相關的接口--> 8 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> 9 <!-- 這個權限用於獲取wifi的獲取權限,wifi信息會用來進行網絡定位--> 10 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> 11 <!-- 用於讀取手機當前的狀態--> 12 <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> 13 <!-- 寫入擴展存儲,向擴展卡寫入數據,用於寫入離線定位數據--> 14 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> 15 <!-- 訪問網絡,網絡定位需要上網--> 16 <uses-permission android:name="android.permission.INTERNET" /> 17 <!—SD卡讀取權限,用戶寫入離線定位數據--> 18 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> 19 <!--允許應用讀取低級別的系統日志文件 --> 20 <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
在application標簽中聲明service組件,每個app擁有自己單獨的定位service
1 <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"> 2 </service>
設置AcessKey
1 <meta-data 2 android:name="com.baidu.lbsapi.API_KEY" 3 android:value="key" />//key:開發者申請的key
例如,我的AndroidManifest.xml文件如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.testandroid" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="8" 9 android:targetSdkVersion="19" /> 10 11 <!-- 這個權限用於進行網絡定位 --> 12 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" > 13 </uses-permission> 14 <!-- 這個權限用於訪問GPS定位 --> 15 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" > 16 </uses-permission> 17 <!-- 用於訪問wifi網絡信息,wifi信息會用於進行網絡定位 --> 18 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" > 19 </uses-permission> 20 <!-- 獲取運營商信息,用於支持提供運營商信息相關的接口 --> 21 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" > 22 </uses-permission> 23 <!-- 這個權限用於獲取wifi的獲取權限,wifi信息會用來進行網絡定位 --> 24 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" > 25 </uses-permission> 26 <!-- 用於讀取手機當前的狀態 --> 27 <uses-permission android:name="android.permission.READ_PHONE_STATE" > 28 </uses-permission> 29 <!-- 寫入擴展存儲,向擴展卡寫入數據,用於寫入離線定位數據 --> 30 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > 31 </uses-permission> 32 <!-- 訪問網絡,網絡定位需要上網 --> 33 <uses-permission android:name="android.permission.INTERNET" /> 34 <!-- SD卡讀取權限,用戶寫入離線定位數據 --> 35 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" > 36 </uses-permission> 37 <!-- 允許應用讀取低級別的系統日志文件 --> 38 <uses-permission android:name="android.permission.READ_LOGS" > 39 </uses-permission> 40 41 <application 42 android:allowBackup="true" 43 android:icon="@drawable/ic_launcher" 44 android:label="@string/app_name" 45 android:theme="@style/AppTheme" > 46 <activity 47 android:name="com.example.testandroid.ui.LocationActivity" 48 android:label="@string/app_name" > 49 <intent-filter> 50 <action android:name="android.intent.action.MAIN" /> 51 52 <category android:name="android.intent.category.LAUNCHER" /> 53 </intent-filter> 54 </activity> 55 56 <service 57 android:name="com.baidu.location.f" 58 android:enabled="true" 59 android:process=":remote" > 60 <intent-filter> 61 <action android:name="com.baidu.location.service_v2.2" > 62 </action> 63 </intent-filter> 64 </service> 65 <!-- meta-data需要寫在application中 --> 66 <meta-data 67 android:name="com.baidu.lbsapi.API_KEY" 68 android:value="your key" /><!-- 這里的Key需要改成你申請的Key --> 69 </application> 70 71 </manifest>
測試應用中,只有一個Activity:
1 package com.example.testandroid.ui; 2 3 import android.os.Bundle; 4 import android.support.v7.app.ActionBarActivity; 5 import android.view.View; 6 import android.widget.Button; 7 import android.widget.TextView; 8 9 import com.baidu.location.BDLocation; 10 import com.baidu.location.BDLocationListener; 11 import com.baidu.location.LocationClient; 12 import com.baidu.location.LocationClientOption; 13 import com.baidu.location.LocationClientOption.LocationMode; 14 import com.example.testandroid.R; 15 16 public class LocationActivity extends ActionBarActivity { 17 18 private TextView location_tv1; 19 private Button startLocation; 20 private boolean isStart = false; 21 public LocationClient mLocationClient; 22 public MyLocationListener mMyLocationListener; 23 private long times = 0; 24 25 @Override 26 protected void onCreate(Bundle savedInstanceState) { 27 super.onCreate(savedInstanceState); 28 setContentView(R.layout.activity_location); 29 initView(); 30 init(); 31 } 32 33 private void initView() { 34 location_tv1 = (TextView) findViewById(R.id.location_tv1); 35 startLocation = (Button) findViewById(R.id.startLocation); 36 startLocation.setOnClickListener(new View.OnClickListener() { 37 38 @Override 39 public void onClick(View v) { 40 ctlLocService(); 41 } 42 }); 43 } 44 45 /** 46 * 47 * @Title: init 48 * @Description: 初始化相關服務及監聽 49 * @return void 50 * @throws 51 * @author creasylai19@gmail.com 52 */ 53 private void init() { 54 mLocationClient = new LocationClient(this.getApplicationContext()); 55 mMyLocationListener = new MyLocationListener(); 56 mLocationClient.registerLocationListener(mMyLocationListener); 57 InitLocation(); 58 } 59 60 /** 61 * 62 * @Title: ctlLocService 63 * @Description: 控制定位服務的開關 64 * @return void 65 * @throws 66 * @author creasylai19@gmail.com 67 */ 68 private void ctlLocService() { 69 if (!isStart) { 70 isStart = true; 71 mLocationClient.start(); 72 startLocation.setText("停止定位"); 73 } else { 74 isStart = false; 75 mLocationClient.stop(); 76 startLocation.setText("啟動定位"); 77 } 78 } 79 80 private void InitLocation() { 81 LocationClientOption option = new LocationClientOption(); 82 option.setLocationMode(LocationMode.Hight_Accuracy);// 設置定位模式 83 /** 84 * 返回國測局經緯度坐標系 coor=gcj02 85 * 返回百度墨卡托坐標系 coor=bd09 86 * 返回百度經緯度坐標系 coor=bd09ll 87 */ 88 option.setCoorType("bd09ll");// 百度手機地圖對外接口中的坐標系默認是bd09ll,如果配合百度地圖產品的話,需要注意坐標系對應問題 89 /** 90 * 當所設的整數值大於等於1000(ms)時,定位SDK內部使用定時定位模式。調用requestLocation() 91 * 后,每隔設定的時間,定位SDK就會進行一次定位。 92 * 如果定位SDK根據定位依據發現位置沒有發生變化,就不會發起網絡請求,返回上一次定位的結果; 93 * 如果發現位置改變,就進行網絡請求進行定位,得到新的定位結果。定時定位時,調用一次requestLocation,會定時監聽到定位結果。 94 * 95 * 當不設此項,或者所設的整數值小於1000(ms)時,采用一次定位模式。每調用一次requestLocation(), 96 * 定位SDK會發起一次定位。請求定位與監聽結果一一對應。 97 * 98 * 設定了定時定位后,可以熱切換成一次定位,需要重新設置時間間隔小於1000(ms)即可。locationClient對象stop后,將不再進行定位 99 * 。 如果設定了定時定位模式后,多次調用requestLocation(),則是每隔一段時間進行一次定位,同時額外的定位請求也會進行定位, 100 * 但頻率不會超過1秒一次。 101 */ 102 option.setScanSpan(5000);// 設置發起定位請求的間隔時間為5000ms 103 option.setIsNeedAddress(true); // 返回的定位結果包含地址信息 104 option.setNeedDeviceDirect(true); // 返回的定位結果包含手機機頭的方向 105 option.setOpenGps(true); // 打開GPS 106 // String 值為all時,表示返回地址信息,其他值都表示不返回地址信息(官方指南說有這個方法,但類中卻沒有,不知道為什么) 107 // option.setAddrType("all"); 108 option.setProdName("com.example.textandroid"); // 設置產品線名稱,百度建議 109 mLocationClient.setLocOption(option); 110 } 111 112 protected void onStop() { 113 mLocationClient.stop(); 114 super.onStop(); 115 } 116 117 public class MyLocationListener implements BDLocationListener { 118 119 @Override 120 public void onReceiveLocation(BDLocation location) { 121 StringBuffer sb = new StringBuffer(256); 122 sb.append("第" + (++times) + "獲取定位"); 123 sb.append("\ntime : "); 124 sb.append(location.getTime()); 125 sb.append("\nerror code : "); 126 sb.append(location.getLocType()); 127 sb.append("\nlatitude : "); 128 sb.append(location.getLatitude()); 129 sb.append("\nlontitude : "); 130 sb.append(location.getLongitude()); 131 sb.append("\nradius : "); 132 sb.append(location.getRadius()); 133 if (location.getLocType() == BDLocation.TypeGpsLocation) { 134 sb.append("\nspeed : "); 135 sb.append(location.getSpeed()); 136 sb.append("\nsatellite : "); 137 sb.append(location.getSatelliteNumber()); 138 sb.append("\ndirection : "); 139 sb.append("\naddr : "); 140 sb.append(location.getAddrStr()); 141 sb.append(location.getDirection()); 142 } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { 143 sb.append("\naddr : "); 144 sb.append(location.getAddrStr()); 145 // 運營商信息 146 sb.append("\noperationers : "); 147 sb.append(location.getOperators()); 148 } 149 location_tv1.setText(sb.toString()); 150 } 151 152 } 153 }
相應的layout文件如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingLeft="@dimen/activity_horizontal_margin" 6 android:paddingRight="@dimen/activity_horizontal_margin" 7 tools:context="com.example.testandroid.ui.LocationActivity" 8 android:orientation="vertical" > 9 10 <TextView 11 android:id="@+id/location_tv1" 12 android:layout_width="match_parent" 13 android:layout_height="0dp" 14 android:layout_weight="1" 15 android:text="@string/hello_world" /> 16 17 <Button 18 android:id="@+id/startLocation" 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:layout_gravity="bottom" 22 android:text="啟動定位" /> 23 24 </LinearLayout>
運行應用,得到的運行結果的一個截屏如下:
其實,這些調用第三方接口,參考指南直接看官方文檔最好,百度定位的官網指南(不過這個指南有不少錯誤的,有些指導還是以前老版本的,沒有做好更新):