diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/Gps.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/Gps.java
new file mode 100644
index 0000000..d8b4376
--- /dev/null
+++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/Gps.java
@@ -0,0 +1,33 @@
+package com.dahe.mylibrary.utils;
+
+/**
+ * @ClassName Gps
+ * @Author john
+ * @Date 2024/12/13 17:25
+ * @Description TODO
+ */
+public class Gps {
+ private double wgLon;
+ private double wgLat;
+
+ public Gps(double wgLat,double wgLon) {
+ this.wgLat = wgLat;
+ this.wgLon = wgLon;
+ }
+
+ public double getWgLon() {
+ return wgLon;
+ }
+
+ public void setWgLon(double wgLon) {
+ this.wgLon = wgLon;
+ }
+
+ public double getWgLat() {
+ return wgLat;
+ }
+
+ public void setWgLat(double wgLat) {
+ this.wgLat = wgLat;
+ }
+}
diff --git a/mylibrary/src/main/java/com/dahe/mylibrary/utils/RxLocationUtils.java b/mylibrary/src/main/java/com/dahe/mylibrary/utils/RxLocationUtils.java
new file mode 100644
index 0000000..5e8b955
--- /dev/null
+++ b/mylibrary/src/main/java/com/dahe/mylibrary/utils/RxLocationUtils.java
@@ -0,0 +1,539 @@
+package com.dahe.mylibrary.utils;
+
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.location.Address;
+import android.location.Criteria;
+import android.location.Geocoder;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * @author ondear
+ * time : 16/11/13
+ * desc : 定位相关工具类
+ */
+public class RxLocationUtils {
+
+ public static double pi = 3.1415926535897932384626;
+ public static double a = 6378245.0;
+ public static double ee = 0.00669342162296594323;
+ private static OnLocationChangeListener mListener;
+ private static MyLocationListener myLocationListener;
+ private static LocationManager mLocationManager;
+
+ /**
+ * 判断Gps是否可用
+ *
+ * @return {@code true}: 是
{@code false}: 否
+ */
+ public static boolean isGpsEnabled(Context context) {
+ LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ return lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
+ }
+
+ /**
+ * 判断定位是否可用
+ *
+ * @return {@code true}: 是
{@code false}: 否
+ */
+ public static boolean isLocationEnabled(Context context) {
+ LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ return lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) || lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
+ }
+
+ /**
+ * 打开Gps设置界面
+ */
+ public static void openGpsSettings(Context context) {
+ Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ }
+
+ /**
+ * 注册
+ *
使用完记得调用{@link #unregister()}
+ *需添加权限 {@code
需添加权限 {@code
需添加权限 {@code
如果{@code minDistance}为0,则通过{@code minTime}来定时更新;
+ *{@code minDistance}不为0,则以{@code minDistance}为准;
+ *两者都为0,则随时刷新。
+ * + * @param minTime 位置信息更新周期(单位:毫秒) + * @param minDistance 位置变化最小距离:当位置距离变化超过此值时,将更新位置信息(单位:米) + * @param listener 位置刷新的回调接口 + * @return {@code true}: 初始化成功+ * World Geodetic System ==> Mars Geodetic System + * + * @param lon 经度 + * @param lat 纬度 + * @return GPS实体类 + */ + public static Gps GPS84ToGCJ02(double lat, double lon) { + if (outOfChina(lat, lon)) { + return null; + } + double dLat = transformLat(lon - 105.0, lat - 35.0); + double dLon = transformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * pi; + double magic = Math.sin(radLat); + magic = 1 - ee * magic * magic; + double sqrtMagic = Math.sqrt(magic); + dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); + dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + return new Gps(mgLat, mgLon); + } + + /** + * [国测局坐标系] 火星坐标系 (GCJ-02) + * 转换成 + * 国际 GPS84 坐标系 + * + * @param lon 火星经度 + * @param lat 火星纬度 + */ + public static Gps GCJ02ToGPS84(double lat, double lon) { + Gps gps = transform(lat, lon); + double lontitude = lon * 2 - gps.getWgLon(); + double latitude = lat * 2 - gps.getWgLat(); + return new Gps(latitude, lontitude); + } + + /** + * 火星坐标系 (GCJ-02) + * 转换成 + * 百度坐标系 (BD-09) + * + * @param gg_lon 经度 + * @param gg_lat 纬度 + */ + public static Gps GCJ02ToBD09(double gg_lat, double gg_lon) { + double x = gg_lon, y = gg_lat; + double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi); + double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi); + double bd_lon = z * Math.cos(theta) + 0.0065; + double bd_lat = z * Math.sin(theta) + 0.006; + return new Gps(bd_lat, bd_lon); + } + + /** + * 国际 GPS84 坐标系 + * 转换成 + * 百度坐标系 (BD-09) + * + * @param lon 经度 + * @param lat 纬度 + */ + public static Gps GPS84ToBD09(double lat, double lon) { + Gps gps = GPS84ToGCJ02(lat,lon); + if (gps == null) { + return new Gps(lat,lon); + } + //GCJ-02 转 BD-09 + return GCJ02ToBD09(gps.getWgLat(), gps.getWgLon()); + } + + /** + * 百度坐标系 (BD-09) + * 转换成 + * 火星坐标系 (GCJ-02) + * + * @param bd_lon 百度*经度 + * @param bd_lat 百度*纬度 + * @return GPS实体类 + */ + public static Gps BD09ToGCJ02(double bd_lat, double bd_lon) { + double x = bd_lon - 0.0065, y = bd_lat - 0.006; + double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi); + double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi); + double gg_lon = z * Math.cos(theta); + double gg_lat = z * Math.sin(theta); + return new Gps(gg_lat, gg_lon); + } + + /** + * 百度坐标系 (BD-09) + * 转换成 + * 国际 GPS84 坐标系 + * + * @param bd_lon 百度*经度 + * @param bd_lat 百度*纬度 + * @return GPS实体类 + */ + public static Gps BD09ToGPS84(double bd_lat, double bd_lon) { + Gps gcj02 = BD09ToGCJ02(bd_lat, bd_lon); + Gps map84 = GCJ02ToGPS84(gcj02.getWgLat(), + gcj02.getWgLon()); + return map84; + + } + + /** + * 不在中国范围内 + * + * @param lon 经度 + * @param lat 纬度 + * @return boolean值 + */ + public static boolean outOfChina(double lat, double lon) { + if (lon < 72.004 || lon > 137.8347) + return true; + return lat < 0.8293 || lat > 55.8271; + } + + /** + * 转化算法 + * + * @param lon + * @param lat + * @return + */ + public static Gps transform(double lat, double lon) { + if (outOfChina(lat, lon)) { + return new Gps(lat, lon); + } + double dLat = transformLat(lon - 105.0, lat - 35.0); + double dLon = transformLon(lon - 105.0, lat - 35.0); + double radLat = lat / 180.0 * pi; + double magic = Math.sin(radLat); + magic = 1 - ee * magic * magic; + double sqrtMagic = Math.sqrt(magic); + dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); + dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); + double mgLat = lat + dLat; + double mgLon = lon + dLon; + return new Gps(mgLat, mgLon); + } + + /** + * 纬度转化算法 + * + * @param x + * @param y + * @return + */ + public static double transformLat(double x, double y) { + double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + + 0.2 * Math.sqrt(Math.abs(x)); + ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0; + ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0; + return ret; + } + + /** + * 经度转化算法 + * + * @param x + * @param y + * @return + */ + public static double transformLon(double x, double y) { + double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 + * Math.sqrt(Math.abs(x)); + ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0; + ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 + * pi)) * 2.0 / 3.0; + return ret; + } + + public interface OnLocationChangeListener { + + /** + * 获取最后一次保留的坐标 + * + * @param location 坐标 + */ + void getLastKnownLocation(Location location); + + /** + * 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 + * + * @param location 坐标 + */ + void onLocationChanged(Location location); + + /** + * provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数 + * + * @param provider 提供者 + * @param status 状态 + * @param extras provider可选包 + */ + void onStatusChanged(String provider, int status, Bundle extras);//位置状态发生改变 + + void onProviderEnabled(String provider); + + void onProviderDisabled(String provider); + } + + private static class MyLocationListener + implements LocationListener { + /** + * 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 + * + * @param location 坐标 + */ + @Override + public void onLocationChanged(Location location) { + if (mListener != null) { + mListener.onLocationChanged(location); + } + } + + /** + * provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数 + * + * @param provider 提供者 + * @param status 状态 + * @param extras provider可选包 + */ + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + if (mListener != null) { + mListener.onStatusChanged(provider, status, extras); + } + switch (status) { + case LocationProvider.AVAILABLE: + Log.d("onStatusChanged", "当前GPS状态为可见状态"); + break; + case LocationProvider.OUT_OF_SERVICE: + Log.d("onStatusChanged", "当前GPS状态为服务区外状态"); + break; + case LocationProvider.TEMPORARILY_UNAVAILABLE: + Log.d("onStatusChanged", "当前GPS状态为暂停服务状态"); + break; + } + } + + /** + * provider被enable时触发此函数,比如GPS被打开 + */ + @Override + public void onProviderEnabled(String provider) { + if (mListener != null) { + mListener.onProviderEnabled(provider); + } + } + + /** + * provider被disable时触发此函数,比如GPS被关闭 + */ + @Override + public void onProviderDisabled(String provider) { + if (mListener != null) { + mListener.onProviderDisabled(provider); + } + } + } + //===========================================坐标转换工具end==================================== + + + + private static final double EARTH_RADIUS = 6378137.0; //地球半径 + + + /** + * 计算两个经纬度之间的距离 + * + * @param longitude + * @param latitude + * @param longitude2 + * @param latitude2 + * @return 单位米 + */ + public static double getDistance(double longitude, double latitude, double longitude2, double latitude2) { + double lat1 = rad(latitude); + double lat2 = rad(latitude2); + double a = lat1 - lat2; + double b = rad(longitude) - rad(longitude2); + double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2))); + s = s * EARTH_RADIUS; + s = Math.round(s * 10000) / 10000; //四舍五入 + return s; + } + + /** + * 弧度换为角度 + * @param d + * @return + */ + private static double rad(double d) { + return d * Math.PI / 180.0; + } +} +