Android原生Gps獲取定位

去年公司寫東西用到了這個,然後遺忘了,今年又來一波這個功能整理一下吧。

老樣子,拷貝可用!!!

首先是工具類:

GPS定位

public class GPSLocation implements LocationListener {
    private GPSLocationListener mGpsLocationListener;


    public GPSLocation(GPSLocationListener gpsLocationListener) {
        this.mGpsLocationListener = gpsLocationListener;
    }

    @Override
    public void onLocationChanged(Location location) {
        if (location != null) {
            mGpsLocationListener.UpdateLocation(location);
        }
    }


    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        mGpsLocationListener.UpdateStatus(provider, status, extras);
        switch (status) {
            case LocationProvider.AVAILABLE:
                mGpsLocationListener.UpdateGPSProviderStatus(GPSProviderStatus.GPS_AVAILABLE);
                break;
            case LocationProvider.OUT_OF_SERVICE:
                mGpsLocationListener.UpdateGPSProviderStatus(GPSProviderStatus.GPS_OUT_OF_SERVICE);
                break;
            case LocationProvider.TEMPORARILY_UNAVAILABLE:
                mGpsLocationListener.UpdateGPSProviderStatus(GPSProviderStatus.GPS_TEMPORARILY_UNAVAILABLE);
                break;
        }
    }

    @Override
    public void onProviderEnabled(String provider) {
        mGpsLocationListener.UpdateGPSProviderStatus(GPSProviderStatus.GPS_ENABLED);
    }

    @Override
    public void onProviderDisabled(String provider) {
        mGpsLocationListener.UpdateGPSProviderStatus(GPSProviderStatus.GPS_DISABLED);
    }
}

GPS管理者類
public class GPSLocationManager {

    private static final String GPS_LOCATION_NAME = android.location.LocationManager.GPS_PROVIDER;
    private static GPSLocationManager gpsLocationManager;
    private static Object objLock = new Object();
    private boolean isGpsEnabled;
    private static String mLocateType;
    private WeakReference<Activity> mContext;
    private LocationManager locationManager;
    private GPSLocation mGPSLocation;
    private boolean isOPenGps;
    private long mMinTime;
    private float mMinDistance;
    private Handler handler;
    private Timer timer ;
    private TimerTask task;
    private Activity context;
    private GPSLocationManager(Activity context) {
        initData(context);
        this.context= context;
    }

    private void initData(Activity context) {
        this.mContext = new WeakReference<>(context);
        if (mContext.get() != null) {
            locationManager = (LocationManager) (mContext.get().getSystemService(Context.LOCATION_SERVICE));
        }
        //定位類型:GPS
        mLocateType = locationManager.GPS_PROVIDER;
        //默認不強制打開GPS設置面板
        isOPenGps = false;
        //默認定位時間間隔爲30分鐘,此處與下面都爲30分鐘
        mMinTime = 30*60*1000;
        //mMinTime = 10000;
        //默認位置可更新的最短距離爲0m
        mMinDistance = 0;
    }

    public static GPSLocationManager getInstances(Activity context) {
        if (gpsLocationManager == null) {
            synchronized (objLock) {
                if (gpsLocationManager == null) {
                    gpsLocationManager = new GPSLocationManager(context);
                }
            }
        }
        return gpsLocationManager;
    }

    public void setHandler(final Handler handler) {
        this.handler = handler;
    }

    /**
     * 方法描述:設置發起定位請求的間隔時長
     *
     * @param minTime 定位間隔時長(單位ms)
     */
    public void setScanSpan(long minTime) {
        this.mMinTime = minTime;
    }

    /**
     * 方法描述:設置位置更新的最短距離
     *
     * @param minDistance 最短距離(單位m)
     */
    public void setMinDistance(float minDistance) {
        this.mMinDistance = minDistance;
    }

    /**
     * 方法描述:開啓定位(默認情況下不會強制要求用戶打開GPS設置面板)
     *
     * @param gpsLocationListener
     */
    public void start(GPSLocationListener gpsLocationListener) {

        this.start(gpsLocationListener, isOPenGps);
    }

    /**
     * 方法描述:開啓定位
     *
     * @param gpsLocationListener
     * @param isOpenGps           當用戶GPS未開啓時是否強制用戶開啓GPS
     */
    public void start(GPSLocationListener gpsLocationListener, boolean isOpenGps) {
        this.isOPenGps = isOpenGps;
        if (mContext.get() == null) {
            return;
        }
        mGPSLocation = new GPSLocation(gpsLocationListener);
        isGpsEnabled = locationManager.isProviderEnabled(GPS_LOCATION_NAME);
        if (!isGpsEnabled && isOPenGps) {
            openGPS();
            return;
        }
        if (Build.VERSION.SDK_INT >= 23) {
            if (ActivityCompat.checkSelfPermission(mContext.get(), Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
                    (mContext.get(), Manifest.permission.ACCESS_COARSE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(context,new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},1);
                return;
            }
        }
     /*   boolean xx= true;
        Location lastKnownLocation = null;
        while(xx){

             lastKnownLocation = locationManager.getLastKnownLocation(mLocateType);
            if(lastKnownLocation != null){
                xx=false;
            }
        }
            mGPSLocation.onLocationChanged(lastKnownLocation);
        */
        Location lastKnownLocation = null;
        lastKnownLocation = locationManager.getLastKnownLocation(mLocateType);
        if(lastKnownLocation == null){
            lastKnownLocation =locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }
        mGPSLocation.onLocationChanged(lastKnownLocation);
        //備註:參數2和3,如果參數3不爲0,則以參數3爲準;參數3爲0,則通過時間來定時更新;兩者爲0,則隨時刷新
        locationManager.requestLocationUpdates(mLocateType,mMinTime, 0, mGPSLocation);//mMinTime


    }

    public void start_TimerTask(){
        cancelTimer();
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                handler.sendEmptyMessage(0);
            }
        }, 10,  30 * 1000 * 60);//定時每30分鐘上傳一次

    }


    /**
     * 方法描述:轉到手機設置界面,用戶設置GPS
     */
    public void openGPS() {
        Toast.makeText(mContext.get(), "請打開GPS設置", Toast.LENGTH_SHORT).show();
     /*  if (Build.VERSION.SDK_INT > 15) {
            Intent intent = new Intent(
                    Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.get().startActivityForResult(intent, 2);
        }*/
    }

    /**
     * 方法描述:終止GPS定位,該方法最好在onPause()中調用
     */
    public void stop() {
        if (mContext.get() != null) {
            if (ActivityCompat.checkSelfPermission(mContext.get(), Manifest.permission.ACCESS_FINE_LOCATION) !=
                    PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext.get(),
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            locationManager.removeUpdates(mGPSLocation);
        }
        cancelTimer();
    }
    private void cancelTimer(){
        if(timer != null) {
            timer.cancel();
            timer = null;
        }
    }
}
GPS定位信息
public class GPSProviderStatus {

    //用戶手動開啓GPS
    public static final int GPS_ENABLED = 0;
    //用戶手動關閉GPS
    public static final int GPS_DISABLED = 1;
    //服務已停止,並且在短時間內不會改變
    public static final int GPS_OUT_OF_SERVICE = 2;
    //服務暫時停止,並且在短時間內會恢復
    public static final int GPS_TEMPORARILY_UNAVAILABLE = 3;
    //服務正常有效
    public static final int GPS_AVAILABLE = 4;
}

GPS定位事件

public interface GPSLocationListener {
    /**
     * 方法描述:位置信息發生改變時被調用
     *
     * @param location 更新位置後的新的Location對象
     */
    void UpdateLocation(Location location);

    /**
     * 方法描述:provider定位源類型變化時被調用
     *
     * @param provider provider的類型
     * @param status   provider狀態
     * @param extras   provider的一些設置參數(如高精度、低功耗等)
     */
    void UpdateStatus(String provider, int status, Bundle extras);

    /**
     * 方法描述:GPS狀態發生改變時被調用(GPS手動啓動、手動關閉、GPS不在服務區、GPS佔時不可用、GPS可用)
     *
     * @param gpsStatus 詳見{@link GPSProviderStatus}
     */
    void UpdateGPSProviderStatus(int gpsStatus);

}

 

使用方法,在點擊事件裏調用:

TextView textView = (TextView) findViewById(R.id.getLaocation);
textView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        
GPSLocationManager gpsManager = GPSLocationManager.getInstances(MainActivity.this);
        gpsManager.setHandler(handler);
        //開啓定位
        GPS_FIRST_FIX = true;
        gpsManager.start(new MyListener(), true);
    }
});

自定義MyListen

class MyListener implements GPSLocationListener {

    @Override
    public void UpdateLocation(Location location) {
        if (location != null) {
            log = location.getLongitude();
            lat = location.getLatitude();
            if (GPS_FIRST_FIX = true) {
                gpsManager.start_TimerTask();
                GPS_FIRST_FIX = false;
            }
            Log.e("gps==", "經度:" + location.getLongitude() + "\n緯度:" + location.getLatitude());
        }
    }

    @Override
    public void UpdateStatus(String provider, int status, Bundle extras) {
        if ("gps" == provider) {
            Log.e("UpdateStatus--gps", "定位類型:" + provider);
        }
    }

    @Override
    public void UpdateGPSProviderStatus(int gpsStatus) {
        switch (gpsStatus) {

            case GPSProviderStatus.GPS_ENABLED:
                //   Toast.makeText(MainActivity.this, "GPS開啓", Toast.LENGTH_SHORT).show();
                break;
            case GPSProviderStatus.GPS_DISABLED:
                //    Toast.makeText(MainActivity.this, "GPS關閉", Toast.LENGTH_SHORT).show();
                break;
            case GPSProviderStatus.GPS_OUT_OF_SERVICE:
                //  Toast.makeText(MainActivity.this, "GPS不可用", Toast.LENGTH_SHORT).show();
                break;
            case GPSProviderStatus.GPS_TEMPORARILY_UNAVAILABLE:
                //  Toast.makeText(MainActivity.this, "當前GPS狀態爲暫停服務狀態", Toast.LENGTH_SHORT).show();
                break;
            case GPSProviderStatus.GPS_AVAILABLE:
                //     Toast.makeText(MainActivity.this, "GPS可用啦", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

在Handler獲取詳細地區信息:

Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        // TODO Auto-generated method stub
        // 要做的事情
        super.handleMessage(msg);
        Geocoder gc = new Geocoder(MainActivity.this, Locale.getDefault());
        List<Address> locationList = null;
        try {
            locationList = gc.getFromLocation(lat, log, 1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (locationList.size() > 0) {
            Address address = locationList.get(0);//得到Address實例
            String locality = address.getLocality();//得到城市名稱,比如:北京市
            String addressLine = address.getAddressLine(0);//得到周邊信息,包括街道等,i=0,得到街道名稱
            Log.e("motejia", "handleMessage: =============="+locality+"========="+addressLine);
        }
        //在Handler每次運行時候獲取數據
    }
};

獲取地址定位會有微小偏差,原生定位導致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章