1. 程式人生 > >百度地圖開發(七)方向感測器指向方向--指南針

百度地圖開發(七)方向感測器指向方向--指南針

效果圖:

用到的小圖,自行下載:

原理就是利用方向感測判斷機頭方向傳值給定位:

方向感測程式碼:

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

/*
 * @Comment :
 * @Created :2018/10/25 19:01
 * @Name : YJ
 */public class MyOrientationListener implements SensorEventListener {

    private SensorManager mSensorManager;
    private Context mContext;
    private Sensor mSensor;
    private float lastX;


    private OnOrientationListener mOnOrientationListener;

    public void setmOnOrientationListener(OnOrientationListener mOnOrientationListener) {
        this.mOnOrientationListener = mOnOrientationListener;
    }

    public MyOrientationListener(Context context) {
        this.mContext = context;
    }


    public void star() {
        mSensorManager = (SensorManager) mContext
                .getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            //獲得方向感測器
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        }

        if (mSensor != null) {
            mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI);
        }
    }

    public void stop() {
        //停止定位
        mSensorManager.unregisterListener(this);
    }


    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
            float x = event.values[SensorManager.DATA_X];
            if (Math.abs(x - lastX) > 1.0) {
                if (mOnOrientationListener != null) {
                    mOnOrientationListener.onOrientationChanged(x);
                }
            }

            lastX = x;
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }


    public interface OnOrientationListener {
        void onOrientationChanged(float x);
    }
}

 然後在需要用到的地方呼叫:

private MyOrientationListener myOrientationListener;

這個再onCreate裡面呼叫

private void initMyOrien() {
        //初始化圖示
        bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.mipmap.jiantou);
        //方向感測器
        myOrientationListener = new MyOrientationListener(this);
        myOrientationListener.setmOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
            @Override
            public void onOrientationChanged(float x) {
                mLastX = x;
            }
        });
    }

最後在地圖監聽裡面呼叫這個方法傳遞過來的方向值就行:

locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .direction(mLastX)// 此處設定開發者獲取到的方向資訊,順時針0-360
                    .latitude(mLatitude)
                    .longitude(mLongitude).build();
            mBaiduMap.setMyLocationData(locData);// 設定定位資料

下面是全部的程式碼:

佈局檔案的程式碼:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.baidu.mapapi.map.MapView
            android:id="@+id/mapview"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </com.baidu.mapapi.map.MapView>

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:layout_centerInParent="true"
            android:paddingBottom="20dp"
            android:src="@mipmap/dingwei2" />

        <ImageView
            android:id="@+id/sa_location"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_margin="10dp"
            android:src="@mipmap/icon_location" />

    </RelativeLayout>

</LinearLayout>

MainActivity裡面的程式碼:

package com.example.administrator.baidumap1;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;

import java.io.PipedInputStream;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private MapView mMapView;
    private BaiduMap mBaiduMap;
    private ImageView mSaLocation;
    private LocationClient mLocationClient;
    private LatLng latLng;
    private boolean isFirstLoc = true;//是否是首次定位
    public BDLocationListener myListener = new MyLocationListener();
    private MyLocationData locData;
    private BitmapDescriptor bitmapDescriptor;
    private MyOrientationListener myOrientationListener;
    private float mLastX;
    private double mLatitude;
    private double mLongitude;
    private PipedInputStream client;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setInit();
        initMap();
        initMyOrien();
    }

    public void setInit() {
        mMapView = findViewById(R.id.mapview);
        mBaiduMap = mMapView.getMap();
        mMapView.showZoomControls(false);
        mSaLocation = findViewById(R.id.sa_location);
        mSaLocation.setOnClickListener(this);
    }

    private void initMyOrien() {
        //初始化圖示
        bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.mipmap.jiantou);
        //方向感測器
        myOrientationListener = new MyOrientationListener(this);
        myOrientationListener.setmOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
            @Override
            public void onOrientationChanged(float x) {
                mLastX = x;
            }
        });
    }

    /**
     * 定位
     */
    private void initMap() {
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);//預設顯示普通地圖
        mBaiduMap.setMyLocationEnabled(true);// 開啟定點陣圖層
        mLocationClient = new LocationClient(getApplicationContext());     //宣告LocationClient類
        initLocation();//配置定位SDK引數
        mLocationClient.registerLocationListener(myListener);    //註冊監聽函式
        mLocationClient.start();//開啟定位
        mLocationClient.requestLocation();//圖片點選事件,回到定位點
    }

    /**
     * 配置定位SDK引數
     */
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setCoorType("bd09ll");//可選,coorType - 取值有3個: 返回國測局經緯度座標系:gcj02 返回百度墨卡託座標系 :bd09 返回百度經緯度座標系 :bd09ll
        Log.e("獲取地址資訊設定", option.getAddrType());//獲取地址資訊設定
        option.setIsNeedAddress(true);//可選,設定是否需要地址資訊,預設不需要
        option.setOpenGps(true); // 是否開啟gps進行定位
        option.setLocationNotify(true);//可選,預設false,設定是否當GPS有效時按照1S/1次頻率輸出GPS結果
        option.setScanSpan(1000);//可選,設定的掃描間隔,單位是毫秒,設定發起定位請求的間隔需要大於等於1000ms才是有效的
        Log.e("獲取設定的Prod欄位值", option.getProdName());
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可選,預設高精度,設定定位模式,高精度,低功耗,僅裝置
        option.setNeedDeviceDirect(true);//在網路定位時,是否需要裝置方向- true:需要 ; false:不需要。預設為false
        option.SetIgnoreCacheException(false);//可選,預設false,設定是否收集CRASH資訊,預設收集
        option.setIgnoreKillProcess(false);//可選,預設true,定位SDK內部是一個SERVICE,並放到了獨立程序,設定是否在stop的時候殺死這個程序,預設不殺死
        option.setIsNeedLocationDescribe(true);//可選,預設false,設定是否需要位置語義化結果,可以在BDLocation
        // .getLocationDescribe裡得到,結果類似於“在北京天安門附近”
        option.setIsNeedLocationPoiList(true);//可選,預設false,設定是否需要POI結果,可以在BDLocation.getPoiList裡得到
        option.setEnableSimulateGps(false);//可選,預設false,設定是否需要過濾GPS模擬結果,預設需要
        mLocationClient.setLocOption(option);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.sa_location:
                //把定位點再次顯現出來
                MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latLng);
                mBaiduMap.animateMapStatus(mapStatusUpdate);
                break;
        }
    }

    //實現BDLocationListener介面,BDLocationListener為結果監聽介面,非同步獲取定位結果
    public class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            latLng = new LatLng(location.getLatitude(), location.getLongitude());
            // 構造定位資料
            mLatitude= location.getLatitude();
            mLongitude=location.getLongitude();
            locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .direction(mLastX)// 此處設定開發者獲取到的方向資訊,順時針0-360
                    .latitude(mLatitude)
                    .longitude(mLongitude).build();
            mBaiduMap.setMyLocationData(locData);// 設定定位資料
            //更新經緯度
            mLatitude = location.getLatitude();
            mLongitude = location.getLongitude();

            //配置定點陣圖層顯示方式,使用自己的定點陣圖標
            //LocationMode定位模式有三種:普通模式,跟隨模式,羅盤模式,在這使用普通模式
            MyLocationConfiguration configuration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, bitmapDescriptor);
            mBaiduMap.setMyLocationConfigeration(configuration);

            if (isFirstLoc) {
                isFirstLoc = false;
                LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                MapStatusUpdate msu= MapStatusUpdateFactory.newLatLng(latLng);
                //改變地圖狀態
                mBaiduMap.setMapStatus(msu);
                MapStatus.Builder builder = new MapStatus.Builder();
                builder.target(latLng).zoom(18.0f);
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

                if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位結果
                    Toast.makeText(MainActivity.this, location.getAddrStr(), Toast.LENGTH_SHORT).show();
                } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 網路定位結果
                    Toast.makeText(MainActivity.this, location.getAddrStr(), Toast.LENGTH_SHORT).show();
                } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 離線定位結果
                    Toast.makeText(MainActivity.this, location.getAddrStr(), Toast.LENGTH_SHORT).show();
                } else if (location.getLocType() == BDLocation.TypeServerError) {//伺服器錯誤
                    Toast.makeText(MainActivity.this, "伺服器錯誤,請檢查", Toast.LENGTH_SHORT).show();
                } else if (location.getLocType() == BDLocation.TypeNetWorkException) {//網路錯誤
                    Toast.makeText(MainActivity.this, "網路錯誤,請檢查", Toast.LENGTH_SHORT).show();
                } else if (location.getLocType() == BDLocation.TypeCriteriaException) {//手機模式錯誤
                    Toast.makeText(MainActivity.this, "手機模式錯誤,請檢查是否飛行", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }


    @Override
    protected void onStart() {
        super.onStart();
        //開啟定位的允許
        mBaiduMap.setMyLocationEnabled(true);
        if (!mLocationClient.isStarted()) {
            mLocationClient.start();
            //開啟方向感測器
            myOrientationListener.star();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        //關閉定位
        mBaiduMap.setMyLocationEnabled(false);
        mLocationClient.stop();
        //停止方向感測器
        myOrientationListener.stop();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }
}

至於方向感測的工具類上面有就不貼了!

下載地址:https://download.csdn.net/download/lanrenxiaowen/10745509