Android 位置服務——BaiduLocation的使用

  這一節我們使用Baidu的定位服務,我們同樣要向上一篇博客一樣下載Baidu定位的SDK。因爲在《Android 位置服務——BaiduMap的使用 》這篇博客中我們已經講過下載步驟,這裏我們不在重複講解下載的過程,不明白的可以直接去上一篇博客中學習。
  這一節的講解是以上一節中百度地圖爲基礎的,使用的是上一節的項目工程。建議大家先看一下《Android 位置服務——BaiduMap的使用 》

  其實這裏的步驟和Baidu定位中提供的文檔是差不多的,此處整理的目的只爲加深樓主的印象。

Baidu定位環境配置

1. 首先將jar包拷貝到libs文件夾下。
2. 通過Android Studio “File——>Project Structure——>Dependencies”中的File Dependency將我們剛纔拷貝的.jar包導入。
3. 其次在main文件夾下創建一個“jniLibs”的文件夾,將包含.so文件的文件夾複製到此處。
4. 配置AndroidManifext.xml.

  • 在application標籤中聲明service組件,每個app擁有自己單獨的定位service
 <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote"></service>
  • 設置AcessKey
<meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="key" />
  • 聲明權限
<!-- 這個權限用於進行網絡定位-->
<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" />
<!-- SD卡讀取權限,用戶寫入離線定位數據-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>

Baidu定位使用

  再次聲明下這裏使用的項目是基於《Android 位置服務——BaiduMap的使用 》這篇博客的,在此基礎上進行定位功能呢的添加。

1.初始化LocationClient類。

public LocationClient mLocationClient = null;
public BDLocationListener myListener = new MyLocationListener();

public void onCreate() {
    mLocationClient = new LocationClient(getApplicationContext());     //聲明LocationClient類
    mLocationClient.registerLocationListener( myListener );    //註冊監聽函數
    //以上兩句卸載setContentView(R.layout.activity_main)之前。
}

2. 配置定位SDK參數。

private void initLocation(){
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationMode.Hight_Accuracy
);//可選,默認高精度,設置定位模式,高精度,低功耗,僅設備
        option.setCoorType("bd09ll");//可選,默認gcj02,設置返回的定位結果座標系
        int span=1000;
        option.setScanSpan(span);//可選,默認0,即僅定位一次,設置發起定位請求的間隔需要大於等於1000ms纔是有效的
        option.setIsNeedAddress(true);//可選,設置是否需要地址信息,默認不需要
        option.setOpenGps(true);//可選,默認false,設置是否使用gps
        option.setLocationNotify(true);//可選,默認false,設置是否當gps有效時按照1S1次頻率輸出GPS結果
        option.setIsNeedLocationDescribe(true);//可選,默認false,設置是否需要位置語義化結果,可以在BDLocation.getLocationDescribe裏得到,結果類似於“在北京天安門附近”
        option.setIsNeedLocationPoiList(true);//可選,默認false,設置是否需要POI結果,可以在BDLocation.getPoiList裏得到
option.setIgnoreKillProcess(false);//可選,默認false,定位SDK內部是一個SERVICE,並放到了獨立進程,設置是否在stop的時候殺死這個進程,默認殺死
        option.SetIgnoreCacheException(false);//可選,默認false,設置是否收集CRASH信息,默認收集
option.setEnableSimulateGps(false);//可選,默認false,設置是否需要過濾gps仿真結果,默認需要
        mLocationClient.setLocOption(option);
    }

高精度定位模式:這種定位模式下,會同時使用網絡定位和GPS定位,優先返回最高精度的定位結果;

低功耗定位模式:這種定位模式下,不會使用GPS,只會使用網絡定位(Wi-Fi和基站定位);

僅用設備定位模式:這種定位模式下,不需要連接網絡,只使用GPS進行定位,這種模式下不支持室內環境的定位。

3. 實現BDLocationListener接口,在艦艇中對定位進行處理。這裏我們做的處理是在定位處方放置定位符號,並添加連線。

        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location.getLocType() == BDLocation.TypeServerError) {

            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {

            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
            } else {

                mTextViewLocation.setText(location.getAddress().address);
                currentLongtitude = location.getLongitude();
                currentLatitude = location.getLatitude();
                mBaiduMap.addOverlay(new MarkerOptions().position(new LatLng(currentLatitude, currentLongtitude))
                        .icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_marka)));
                LatLng p = new LatLng(currentLatitude, currentLongtitude);
                points.add(p);
            }
        }
    }

結果如下:

這裏寫圖片描述

全部代碼如下:

public class MainActivity extends Activity implements View.OnClickListener {

    private Button mButtonStart;//開始定位按鈕
    private Button mButtonOne;//獲取地址一按鈕
    private Button mButtonTwo;//獲取地址二按鈕
    private Button mButtonLine;//劃線按鈕
    private TextView mTextViewLocation;//顯示當前的地址

    MapView mMapView = null;//地圖視圖
    BaiduMap mBaiduMap;//地圖對象
    //連線點的集合
    private List<LatLng> points = new ArrayList<LatLng>();

    //通過地址獲得經緯度
    GeoCoder mSearch = null; // 搜索模塊,也可去掉地圖模塊獨立使用
    public LocationClient mLocationClient = null;
    public BDLocationListener myListener = new MyLocationListener();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //定位
        mLocationClient = new LocationClient(getApplicationContext());     //聲明LocationClient類
        mLocationClient.registerLocationListener(myListener);    //註冊監聽函數
        //使用BaiduMap  SDK
        //在使用SDK各組件之前初始化context信息,傳入ApplicationContext
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        //獲取地圖控件引用
        mMapView = (MapView) findViewById(R.id.bmapView);//獲得地圖視圖的對象
        mBaiduMap = mMapView.getMap();//獲得地圖對象
        //初始化搜索模塊,註冊事件監聽
        mSearch = GeoCoder.newInstance();//獲得搜索的對象
        mSearch.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
            @Override
            public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
                if (geoCodeResult == null || geoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
                    Toast.makeText(MainActivity.this, "抱歉,未能找到結果", Toast.LENGTH_LONG)
                            .show();
                    return;
                }
                mBaiduMap.addOverlay(new MarkerOptions().position(geoCodeResult.getLocation())
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.mipmap.icon_marka)));
                mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(geoCodeResult
                        .getLocation()));


                LatLng p = new LatLng(geoCodeResult.getLocation().latitude, geoCodeResult.getLocation().longitude);//添加點
                points.add(p);
                String strInfo = String.format("緯度:%f 經度:%f",
                        geoCodeResult.getLocation().latitude, geoCodeResult.getLocation().longitude);
                Log.d("data", strInfo);
                Toast.makeText(MainActivity.this, strInfo, Toast.LENGTH_LONG).show();
            }

            @Override
            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
            }
        });

        //獲取佈局中的各個控件對象
        mButtonStart = (Button) findViewById(R.id.button_start);
        mButtonOne = (Button) findViewById(R.id.button_one);
        mButtonTwo = (Button) findViewById(R.id.button_two);
        mButtonLine = (Button) findViewById(R.id.button_three);
        mTextViewLocation = (TextView) findViewById(R.id.textview_location);
        //設置點擊事件
        mButtonStart.setOnClickListener(this);
        mButtonOne.setOnClickListener(this);
        mButtonTwo.setOnClickListener(this);
        mButtonLine.setOnClickListener(this);
        PushManager.startWork(getApplicationContext(), PushConstants.LOGIN_TYPE_API_KEY, "5CjXwt6IZgRSfYxwA8dtOuG5");
    }

    /*
    Activity關閉時將地圖關閉
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity執行onDestroy時執行mMapView.onDestroy(),實現地圖生命週期管理
        mMapView.onDestroy();
    }

    /*
    ActivityonResume時,將地圖onResume。
     */
    @Override
    protected void onResume() {
        super.onResume();
        //在activity執行onResume時執行mMapView. onResume (),實現地圖生命週期管理
        mMapView.onResume();
    }

    /*
    ActivityonPause時,將地圖onPause。
     */
    @Override
    protected void onPause() {
        super.onPause();
        //在activity執行onPause時執行mMapView. onPause (),實現地圖生命週期管理
        mMapView.onPause();
    }

    /*
    初始化定位
     */
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
        );//可選,默認高精度,設置定位模式,高精度,低功耗,僅設備
        option.setCoorType("bd09ll");//可選,默認gcj02,設置返回的定位結果座標系
        int span = 1000;
        option.setScanSpan(span);//可選,默認0,即僅定位一次,設置發起定位請求的間隔需要大於等於1000ms纔是有效的
        option.setIsNeedAddress(true);//可選,設置是否需要地址信息,默認不需要
        option.setOpenGps(true);//可選,默認false,設置是否使用gps
        option.setLocationNotify(true);//可選,默認false,設置是否當gps有效時按照1S1次頻率輸出GPS結果
        option.setIsNeedLocationDescribe(true);//可選,默認false,設置是否需要位置語義化結果,可以在BDLocation.getLocationDescribe裏得到,結果類似於“在北京天安門附近”
        option.setIsNeedLocationPoiList(true);//可選,默認false,設置是否需要POI結果,可以在BDLocation.getPoiList裏得到
        option.setIgnoreKillProcess(false);//可選,默認false,定位SDK內部是一個SERVICE,並放到了獨立進程,設置是否在stop的時候殺死這個進程,默認殺死
        option.SetIgnoreCacheException(false);//可選,默認false,設置是否收集CRASH信息,默認收集
        option.setEnableSimulateGps(false);//可選,默認false,設置是否需要過濾gps仿真結果,默認需要
        mLocationClient.setLocOption(option);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_start:
                initLocation();
                mLocationClient.start();//開始定位
                break;
            case R.id.button_one:
                //獲得天安門的地址
                mSearch.geocode(new GeoCodeOption().city("北京市").address("海淀區中關村海龍大廈"));
                break;
            case R.id.button_two:
                //獲得中關村的地址
                mSearch.geocode(new GeoCodeOption().city("北京市").address("西城區西便門"));
                break;
            case R.id.button_three:
                //獲得當地的地址
                // 添加折線
                OverlayOptions ooPolyline = new PolylineOptions().width(10).color(0xAAFF0000).points(points);
                mBaiduMap.addOverlay(ooPolyline);
                break;
        }
    }

    //獲得當前的經緯度
    private double currentLongtitude;
    private double currentLatitude;

    class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location.getLocType() == BDLocation.TypeServerError) {

            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {

            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
            } else {

                mTextViewLocation.setText(location.getAddress().address);
                currentLongtitude = location.getLongitude();
                currentLatitude = location.getLatitude();
                mBaiduMap.addOverlay(new MarkerOptions().position(new LatLng(currentLatitude, currentLongtitude))
                        .icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_marka)));
                LatLng p = new LatLng(currentLatitude, currentLongtitude);
                points.add(p);
            }
        }
    }
}
發佈了134 篇原創文章 · 獲贊 134 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章