最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實現(xiàn)獲取定位信息的工具類

 更新時間:2025年11月05日 09:45:11   作者:IT樂手  
相信大家在項目中應(yīng)該會經(jīng)常用到這類功能,需要在請求api的時候獲取當前定位信息,以便獲取周邊信息,下面小編就為大家簡單介紹一下如何編寫獲取定位信息的工具類吧

相信大家在項目中應(yīng)該會經(jīng)常用到這類功能,需要在請求api的時候獲取當前定位信息,以便獲取周邊信息,以下是我常用的工具類,大家應(yīng)該用得上

import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Handler;
import android.os.Looper;

import androidx.annotation.NonNull;


/**
 * 描述: 獲取定位信息
 * 創(chuàng)建者: IT樂手
 * 日期: 2025/5/21
 */

public class LocationUtils {

    private final static String TAG = "LocationUtils";

    private static double latitude = 22.665424;
    private static double longitude = 114.075724;

    private static LocationManager locationManager = null;
    private static final Handler mainHandler = new Handler(Looper.getMainLooper());

    /**
     * 獲取經(jīng)緯度
     * @return 經(jīng)緯度字符串
     */
    public static String getLocationString() {
        double[] locations = getLocation();
        String locationStr = locations[0]+","+locations[1];
        AtotoLogger.d(TAG, locationStr);
        return locationStr;
    }

    @SuppressLint("MissingPermission")
    public static double[] getLocation() {
        if (locationManager == null) {
            locationManager = (LocationManager) AppGlobalUtils.getApplication().getSystemService(Context.LOCATION_SERVICE);
        }
        // 檢查GPS/網(wǎng)絡(luò)是否可用
        boolean hasGps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean hasNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        boolean hasPassive = locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
        AtotoLogger.d(TAG, "hasGps = " + hasGps + ", hasNetwork = " + hasNetwork + ", hasPassive = " + hasPassive);
        if (!hasGps && !hasNetwork) {
            AtotoLogger.e(TAG, "Gps and Network are not available");
            return new double[]{0,0};
        }

        Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

        if (location == null) {
            AtotoLogger.d(TAG, "GPS location is null, trying Network location");
            location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }

        if (location == null) {
            AtotoLogger.e(TAG, "Location is null");
            // 在主線程中請求位置更新
            if (Looper.myLooper() == Looper.getMainLooper()) {
                requestLocationUpdatesOnCurrentThread();
            } else {
                mainHandler.post(LocationUtils::requestLocationUpdatesOnCurrentThread);
            }
            return new double[]{latitude,longitude};
        }

        latitude = location.getLatitude();
        longitude = location.getLongitude();
        AtotoLogger.d(TAG, "Latitude: " + latitude + ", Longitude: " + longitude);
        // 處理經(jīng)緯度信息
        return new double[]{latitude, longitude};
    }

    @SuppressLint("MissingPermission")
    private static void requestLocationUpdatesOnCurrentThread() {
        try {
            locationManager.requestLocationUpdates(
                    LocationManager.PASSIVE_PROVIDER,
                    0, // minTime (milliseconds)
                    0,   // minDistance (meters)
                    locationListener
            );
        } catch (Exception e) {
            AtotoLogger.e(TAG, "Request location updates failed: " + e.getMessage());
        }
    }

    private static final android.location.LocationListener locationListener = new android.location.LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            AtotoLogger.d(TAG, "Location updated: Latitude: " + latitude + ", Longitude: " + longitude);

            // 獲取到位置后移除監(jiān)聽,避免持續(xù)更新
            removeLocationUpdates();
        }

        @Override
        public void onStatusChanged(String provider, int status, android.os.Bundle extras) {
        }

        @Override
        public void onProviderEnabled(@NonNull String provider) {
        }

        @Override
        public void onProviderDisabled(@NonNull String provider) {
        }
    };

    /**
     * 移除位置更新監(jiān)聽
     */
    public static void removeLocationUpdates() {
        if (locationManager != null) {
            try {
                locationManager.removeUpdates(locationListener);
            } catch (Exception e) {
                AtotoLogger.e(TAG, "Remove location updates failed: " + e.getMessage());
            }
        }
    }


    @SuppressLint("MissingPermission")
    private static Location getLastKnownLocation() {
        if (locationManager == null) return null;

        Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (location == null) {
            location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }
        return location;
    }
}

方法補充

Android 獲取位置信息

Android 提供 LocationManager 等相關(guān)API用于獲取位置信息。

1.權(quán)限申請

APP申請定位權(quán)限

Manifest 文件中添加以下權(quán)限:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  • ACCESS_COARSE_LOCATION: 允許一個程序訪問CellID或WiFi熱點來獲取粗略的位置
  • ACCESS_FINE_LOCATION: 允許一個程序訪問精良位置(如GPS)

開啟手機定位服務(wù)

只有位置權(quán)限是不夠的,還需要開啟手機定位服務(wù)才能獲取到位置信息。

  /**
   * 判斷是否開啟了GPS或網(wǎng)絡(luò)定位開關(guān)
   */
  public boolean isLocationProviderEnabled() {
    boolean result = false;
    LocationManager locationManager = (LocationManager) SDWanVPNApplication.getAppContext()
        .getSystemService(LOCATION_SERVICE);
    if (locationManager == null) {
      return false;
    }
    if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager
        .isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
      result = true;
    }
    return result;
  }

/**
 * 跳轉(zhuǎn)到設(shè)置界面,引導(dǎo)用戶開啟定位服務(wù)
 */
private void openLocationServer() {
	Intent i = new Intent();
    i.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    startActivityForResult(i, REQUEST_CODE_LOCATION_SERVER);
}

2.監(jiān)聽位置信息

Android 可以通過網(wǎng)絡(luò)或者GPS,獲取位置信息。GPS獲取比較準確,但是在室內(nèi)有時候比較難獲取到。

  private final LocationListener mLocationListener = new LocationListener() {

    // Provider的狀態(tài)在可用、暫時不可用和無服務(wù)三個狀態(tài)直接切換時觸發(fā)此函數(shù)
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
      Log.d(TAG, "onStatusChanged");
    }

    // Provider被enable時觸發(fā)此函數(shù),比如GPS被打開
    @Override
    public void onProviderEnabled(String provider) {
      Log.d(TAG, "onProviderEnabled");

    }

    // Provider被disable時觸發(fā)此函數(shù),比如GPS被關(guān)閉
    @Override
    public void onProviderDisabled(String provider) {
      Log.d(TAG, "onProviderDisabled");

    }

    //當坐標改變時觸發(fā)此函數(shù),如果Provider傳進相同的坐標,它就不會被觸發(fā)
    @Override
    public void onLocationChanged(Location location) {
      Log.d(TAG, String.format("location: longitude: %f, latitude: %f", location.getLongitude(),
          location.getLatitude()));
      //更新位置信息
    }
  };
  
  /**
   * 監(jiān)聽位置變化
   */
  private void initLocationListener() {
    LocationManager locationManager = (LocationManager) MyApplication.getAppContext()
        .getSystemService(LOCATION_SERVICE);
    if (locationManager == null) {
      return;
    }
    
    locationManager
        .requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 10, mLocationListener);
    locationManager
        .requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10, mLocationListener);

  }

其中最重要的就是 requestLocationUpdates 方法,使用指定的提供程序注冊位置信息:

requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener) provider:注冊的位置提供者名稱 minTime:位置更新之間的最小時間間隔,以毫秒為單位 minDistance:位置更新之間的最小距離,以米為單位 listener:位置更新回調(diào)方法

該方法內(nèi)部是通過handler進行通知回調(diào),如果在非主線程調(diào)用該方法,需要多傳入一個Looper參數(shù):

    Looper.prepare();
    locationManager
        .requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 10, mLocationListener, Looper
            .myLooper());
    locationManager
        .requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10, mLocationListener, Looper
            .myLooper());

如果只需要獲取一次位置信息,獲取后可以取消位置監(jiān)聽。

    locationManager.removeUpdates(mLocationListener);

3.獲取最近一次位置信息

有時候由于各種原因例如在室內(nèi)、網(wǎng)絡(luò)問題等,導(dǎo)致注冊的位置監(jiān)聽無法及時返回位置信息,這個時候可以使用 getLastKnownLocation 方法返回一個從給定提供程序獲得的最后一個已知位置數(shù)據(jù)。

  private Location getLastLocation() {
    Location location = null;

    LocationManager locationManager = (LocationManager) SDWanVPNApplication.getAppContext()
        .getSystemService(LOCATION_SERVICE);
    if (locationManager == null) {
      return null;
    }
    List<String> providers = locationManager.getProviders(true);
    for (String provider : providers) {
      Location l = locationManager.getLastKnownLocation(provider);
      if (l == null) {
        continue;
      }
      if (location == null || l.getAccuracy() < location.getAccuracy()) {
        // Found best last known location: %s", l);
        location = l;
      }
    }
    return location;

  }

4.通過經(jīng)緯度獲取詳細地址

Geocoder 相關(guān)API,支持通過經(jīng)緯度獲取詳細位置信息

  public static void getAddress(double latitude, double longitude) {
    List<Address> addressList = null;
    Geocoder geocoder = new Geocoder(MyApplication.getAppContext());
    try {
      addressList = geocoder.getFromLocation(latitude, longitude, 1);
    } catch (IOException e) {
      e.printStackTrace();
    }
    if (addressList != null) {
      for (Address address : addressList) {
        Log.d(TAG, String.format("address: %s", address.toString()));
      }
    }
  }

打印結(jié)果如下:

address: Address[addressLines=[0:"福建省廈門市集美區(qū)誠毅北大街"],feature=null,admin=福建省,sub-admin=后溪鎮(zhèn),locality=廈門市,thoroughfare=誠毅北大街,postalCode=null,countryCode=CN,countryName=中國,hasLatitude=true,latitude=24.622825253598176,hasLongitude=true,longitude=118.05078728444207,phone=null,url=null,extras=null]

5.坐標系介紹

獲取經(jīng)緯度后在地圖上查詢發(fā)現(xiàn),位置存在一定偏移,這個是因為使用的坐標系不一致引起的。

我國出于安全的考慮,會將所有的電子地圖經(jīng)行加偏處理,由真實的地理坐標系又稱地球坐標系(WGS84)轉(zhuǎn)換為火星坐標系(GCJ02),但是使用 location 獲取的經(jīng)緯度又是WGS84坐標系的,所以再其他地圖上顯示會出現(xiàn)位置偏移現(xiàn)象。

目前坐標系主要有以下幾種:

  • WGS84坐標系:地球坐標系,國際通用坐標系
  • GCJ02坐標系:火星坐標系,WGS84坐標系加密后的坐標系,Google國內(nèi)地圖、高德、QQ地圖使用
  • BD09坐標系:百度坐標系,GCJ02坐標系加密后的坐標系

可以調(diào)用你所使用的地圖的服務(wù)商提供的坐標系轉(zhuǎn)換接口進行坐標轉(zhuǎn)換。

到此這篇關(guān)于Android實現(xiàn)獲取定位信息的工具類的文章就介紹到這了,更多相關(guān)Android獲取定位信息內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

浮梁县| 叶城县| 佳木斯市| 高密市| 丰城市| 乡宁县| 紫云| 广宁县| 平武县| 肥西县| 盐城市| 辉南县| 新郑市| 永登县| 沧源| 诸城市| 且末县| 德令哈市| 民乐县| 闵行区| 临朐县| 呼玛县| 孟津县| 普陀区| 巨鹿县| 萝北县| 句容市| 曲靖市| 剑川县| 雅安市| 防城港市| 宣城市| 莱阳市| 即墨市| 历史| 平原县| 神农架林区| 尼勒克县| 黄平县| 徐闻县| 深泽县|