Android學習之百度定位SDK

前天試着用google的三種定位方式,GPS,Network,和基站定位。效果不是很理想。

所以昨天又開始試着用百度定位,最終效果確實比較好(個人感覺,可能是我目前的知識還是太淺薄)

大概整理了一下百度定位的一些知識:

1.這兩者的區別:可能是我沒有用過一些谷歌其它的SDK,但是就目前而言,百度定位還是很好用的,它直接將三種定位都封裝在了一起,開發人員可以通過setLocOption來設置一些他想要選擇的模式。有以下三種定位模式:

1.1:高精度定位模式下(Hight_Accuracy):會同時使用GPS、Wifi和基站定位,返回的是當前條件下精度最好的定位結果

1.2:低功耗定位模式下(Battery_Saving):僅使用網絡定位即Wifi和基站定位,返回的是當前條件下精度最好的網絡定位結果

1.3:僅用設備定位模式下(Device_Sensors):只使用用戶的GPS進行定位。這個模式下,由於GPS芯片鎖定需要時間,首次定位速度會需要一定的時間,而且GPS不適合室內

而且,如果開發一些手機地圖之類的軟件,百度SDK還是很方便的!

2.百度定位的準備工作:

2.1:申請key,需要在百度註冊成爲一個百度開發者,然後申請密鑰。地址:http://developer.baidu.com/map/android-mobile-apply-key.htm

2.2:Android開發申請密鑰時選擇移動端,申請密鑰時需要Android的簽名證書。Android的簽名證書在eclipse-window-preferences-Android-Build裏面可以找到SHA1,就是它了.

3.一個百度定位應用Manifest裏面應該必須部署的東西:

1.,<application>節點下面的meta-data節點:注意,name必須是"com.baidu.lbsapi.API_Key"(我有用過其它的name,結果都會報錯)

<meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="自己的value" />

2.<application>節點下面必須聲明對應的service,原因是,百度定位裏面有一個service,必須註冊才能調用它,要不然無法啓動LocationClient.start()函數

<service android:name="com.baidu.location.f" android:enabled="true" 
android:process=":remote">
        </service>

4.只需要創建一次LocationClient對象,在創建時註冊監聽函數,銷燬時註銷監聽函數,然後用按鈕來控制start()和stop()

4.1:如果設置參數時沒有    option.setScanSpan(),那麼只會在start()時得到一次位置,之後如果需要得到位置需要手動調用函數mLocationClient.requestLocation()。

5.可以參考百度給的那個定位的Demo,裏面實現了很多基礎功能。

6.在監聽函數給主線程傳遞消息時,使用了異步傳輸數據,即Handler-Thread,給主線程綁定一個Handler,然後重寫ReceiveMessage函數,子線程裏面可以通過Handler將消息傳給主線程。

7.其實可以直接自定義一個自己的Application,然後在裏面生成LocationClient,並且註冊監聽,其它Activity只要通過引用其對象就可以實現start()和stop()功能了。

(每個程序運行時創建一個Application類的對象而且只創建一個,Application是單例模式的一個類。)

以下是主要的代碼以及配置文件,最後是完整工程:

public class BaiduLbsDemoActivity extends Activity implements OnClickListener{
	private static final String TAG="BaiduLbsDemoActivity";
	//控件
	private Button btn_StartLocation;
	private Button btn_CheckNetwork;
	//顯示文本
	private TextView txt_LocationView,ModeInfo;
	//定位有關
	 private LocationClient mLocationClient = null;
	 private BDLocationListener myListener;
	 //一些定位的參數
	 private RadioGroup selectMode,selectCoordinates;
	 private EditText frequence;
	 private LocationMode tempMode = LocationMode.Hight_Accuracy;//默認的精度
	 private String tempcoor="gcj02";//默認的座標系
		//是否顯示詳細地理位置
	 private CheckBox checkGeoLocation;
		//一個handler對象,用來線程傳輸
	 private MyHandler myHandler;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Log.i(TAG,"創建"+TAG);
		super.onCreate(savedInstanceState);
		init();		
		
	}
	@Override
	protected void onDestroy() {
		Log.i(TAG,"Destroy!");
		//Activity暫停時,停止定位功能
		super.onPause();
	    if(mLocationClient.isStarted())  
	    {
	    	Log.i(TAG,"停止定位功能!");
	        mLocationClient.stop();  //停止定位
	    }	
	    mLocationClient.unRegisterLocationListener(myListener);//註銷監聽
	}
	/**函數*/
	private void init()
	{
		setContentView(R.layout.baidu_lbs_demo);
		//實現創建handler並與主線程自帶的looper綁定。這裏沒有涉及looper與
        //線程的關聯是因爲主線程在創建之初就已有looper
        myHandler=new MyHandler(BaiduLbsDemoActivity.this);
		mLocationClient=new LocationClient(this.getApplicationContext());
		myListener = new MyLocationListener( myHandler);
		//註冊監聽
		mLocationClient.registerLocationListener(myListener); // 註冊監聽函數
		bindWidgets();
		setListeners();
	}
	/**綁定控件*/
	private void bindWidgets()
	{
		btn_StartLocation=(Button) findViewById(R.id.btn_OnLocation);
		btn_CheckNetwork=(Button) findViewById(R.id.btn_checkNetWork);
		txt_LocationView=(TextView) findViewById(R.id.txt_locationView);
		ModeInfo= (TextView)findViewById(R.id.modeinfo);
		 //定位頻率
		 frequence = (EditText)findViewById(R.id.frequence);
		 //是否顯示具體地址
		 checkGeoLocation = (CheckBox)findViewById(R.id.geolocation);
		//定位模式
		 selectMode = (RadioGroup)findViewById(R.id.selectMode);
			//不同的定位座標
		 selectCoordinates= (RadioGroup)findViewById(R.id.selectCoordinates);
	}
	//設置監聽
	private void setListeners()
	{
		btn_StartLocation.setOnClickListener(this);
		btn_CheckNetwork.setOnClickListener(this);
		selectMode.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			
			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				// TODO Auto-generated method stub
				String ModeInformation = null;
				switch (checkedId) {
				case R.id.radio_high:
					tempMode = LocationMode.Hight_Accuracy;
					ModeInformation = getString(R.string.txt_hight_accuracy_desc);
					break;
				case R.id.radio_low:
					tempMode = LocationMode.Battery_Saving;
					ModeInformation = getString(R.string.txt_saving_battery_desc);
					break;
				case R.id.radio_device:
					tempMode = LocationMode.Device_Sensors;
					ModeInformation = getString(R.string.txt_device_sensor_desc);
					break;
				default:
					break;
				}
				ModeInfo.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;
				}
			}
		});
	}
	/**初始化定位參數*/
	private void initLocation()
	{
		//設置定位參數
		Log.i(TAG,"設置定位參數!");
		setLocationOption();
	}
	/**設置定位的相關參數*/
	private void setLocationOption()
	{	
		LocationClientOption option=new LocationClientOption();
		option.setOpenGps(true);//是否打開GPS
		option.setIsNeedAddress(checkGeoLocation.isChecked());
		option.setLocationMode(tempMode);//設置定位模式
		option.setCoorType(tempcoor);//返回的定位結果是百度經緯度,默認值gcj02
		//設置產品線名稱,強烈建議使用自定義的產品線名稱,方便提供更高效準確的定位服務
		option.setProdName("dlcBaiduLbsDemo");
		int span=1000;
		try {
			span = Integer.valueOf(frequence.getText().toString());
		} catch (Exception e) {
			Log.i(TAG,"設置頻率出錯"+e.getMessage());
		}
		option.setScanSpan(span);//設置發起定位請求的間隔時間爲5000ms
		//設置
		mLocationClient.setLocOption(option);
	}
	/**GPS定位*/
	private void onLocation()
	{
		Log.i(TAG,"GPS定位");
		  if (mLocationClient == null)
		  {
			  Log.d(TAG, "locClient is null");
		  }
		initLocation();
		//一個按鈕實現開始和停止功能
		if(btn_StartLocation.getText().equals(getString(R.string.btn_StartLocation))){
			Log.i(TAG,"開始定位!");
			mLocationClient.start();
			btn_StartLocation.setText(getString(R.string.btn_StopLocation));
			//mLocationClient.requestLocation();
		}else{
			Log.i(TAG,"停止定位!");
			mLocationClient.stop();
			btn_StartLocation.setText(getString(R.string.btn_StartLocation));
			txt_LocationView.setText("已經停止定位!");
		}
            
	}
	/**檢查網絡狀態*/
	private void onCheckNetwork()
	{
		Log.i(TAG,"檢查網絡狀態");
	}
	@Override
	public void onClick(View v) {
		switch(v.getId())
		{
		case R.id.btn_OnLocation:
			onLocation();
			break;
		case R.id.btn_checkNetWork:
			onCheckNetwork();
			break;
		}
	}
	/**myHandler類,繼承Handler,重寫了handleMessage方法*/
	private class MyHandler extends Handler
	{
		private Activity activity;
		public MyHandler(Activity activity)
		{
			 this.activity=new WeakReference<Activity>(activity).get();//使用弱引用避免Handler內存泄露
		}
		//重寫handleMessage,用於處理message
		@Override
		public void handleMessage(Message msg) {
			Log.i(TAG,"主線程接收到消息!");
			//選擇不同的口令類型
			//0-獲取地址失敗  1-獲取地址成功
			switch(msg.arg1)
			{
			case 0:
				//Toast.makeText(activity.getApplicationContext(), "解析地址出錯,不能將經緯度解析爲正確地址!", Toast.LENGTH_SHORT)
				//.show();
				Update(msg);
				break;
			case 1:
				//Toast.makeText(activity.getApplicationContext(), "地址獲取成功!", Toast.LENGTH_SHORT)
				//.show();
				Update(msg);
				break;		
			default:
				//Toast.makeText(activity.getApplicationContext(), "解析地址出錯,未知錯誤!", Toast.LENGTH_SHORT)
				//.show();
				Update(msg);
				break;
			}				
		}
		/**更新UI方法*/	
		private void Update(Message msg)
		{
			//這裏用於更新網絡信息---更新Location
			Bundle b=msg.getData();
			//記得設置bundle時,將Location 鍵的值設爲對應的location
			String myLocation=b.getString("LocationData");
			txt_LocationView.setText(myLocation);
		}
	}
}

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="dlc.test07.baidu.location"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
	<!-- 權限添加 -->

	 <!-- 這個權限用於進行網絡定位 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">
    </uses-permission>
    <!-- 這個權限用於訪問GPS定位 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">
    </uses-permission>
    <!-- 用於訪問wifi網絡信息,wifi信息會用於進行網絡定位 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE">
    </uses-permission>
    <!-- 獲取運營商信息,用於支持提供運營商信息相關的接口 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">
    </uses-permission>
    <!-- 這個權限用於獲取wifi的獲取權限,wifi信息會用來進行網絡定位 -->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE">
    </uses-permission>
    <!-- 用於讀取手機當前的狀態 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE">
    </uses-permission>
    <!-- 寫入擴展存儲,向擴展卡寫入數據,用於寫入離線定位數據 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    </uses-permission>
    <!-- 訪問網絡,網絡定位需要上網 -->
    <uses-permission android:name="android.permission.INTERNET">
    </uses-permission>
    <!-- SD卡讀取權限,用戶寫入離線定位數據 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS">
    </uses-permission>
    <!-- 允許應用讀取低級別的系統日誌文件 -->
    <uses-permission android:name="android.permission.READ_LOGS">
    </uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_baidu_lbs"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        	<!-- meta-data必須放在application裏面 -->
	<!-- value是申請的AK,name是申請的包名 -->
	<meta-data android:name="com.baidu.lbsapi.API_KEY"
	    	   android:value="Fuk70GOYrzVDKqzyZrRpjNtW"/>
	<!-- 聲明開始百度定位的服務 -->
	<service android:name="com.baidu.location.f" android:enabled="true" 
			 android:process=":remote">
        </service>
        <!-- Activity配置 -->
        <activity android:name=".activity.SplashActivity"
            	  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            	  android:configChanges="orientation|keyboardHidden|screenSize"
            >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="dlc.test07.baidu.lbs.start" />
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
         <activity android:name=".activity.MainActivity"
            	  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            	  android:configChanges="orientation|keyboardHidden|screenSize"
            ></activity>
           <activity android:name=".activity.BaiduLbsDemoActivity"
            	  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            	  android:configChanges="orientation|keyboardHidden|screenSize"
            ></activity>
    </application>

</manifest>

完整工程:http://download.csdn.net/detail/u010979495/8113041
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章