由於項目需求,須要使用百度地圖的定位功能,所以去百度地圖開發平臺下載了百度地圖的Android定位SDK最新版本的開發包和示例代碼學習。php
Android 定位SDK地址:http://developer.baidu.com/map/index.php?title=android-locsdkcss
下載地址爲:http://developer.baidu.com/map/index.php?title=android-locsdk/geosdk-android-downloadhtml
下載示例代碼後,導入到相應的IDE工具。代碼有android_studio和eclipse兩個版本。我使用的Eclipse,所以導入Eclipse的版本代碼。java
先申請祕鑰,而後修改AndroidManifest.xml中的代碼,具體要修改的代碼以下:android
<!-- 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/keygit
若是上面的key值不對或者是沒有的話,運行項目會出現下面的結果,其中的error code:505表明key不存在或者非法。api
完成上述步驟後,就能夠運行該項目了。正常運行項目後,以下所示:緩存
====================================================================================網絡
下面來具體看看項目代碼,項目的結構以下圖所示,開發所須要的SDK是最新版本的locSDK_6.11.jar,還有liblocSDK6a.so庫文件app
主要的類有三個,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
====================================================================================