Android10 LocationListener的onStatusChanged被废弃

  在Android10 LocationListener的onStatusChanged被废弃,此回调永远不会在Android Q及以上版本上调用,提供商可以被视为始终处于LocationProvider#AVAILABLE状态。

LocationListener  |  Android Developers

有以下解决方案:

① 使用LocationListenerCompat(设备必须搭载GMS)

② 使用高德sdk、百度sdk或第三方

但是有的项目,这些条件都不满足,这就导致,这个API被废弃,在GPS信号不好的地方,回调不了任何方法来让应用知道GPS信号不佳来进行响应的逻辑处理,本篇文章着重于解决这个问题。

1、创建请求位置的接口

public interface LocationChangeListener {
    void onLocationChanged(double latitude, double longitude);
    default void onProviderEnabled(String provider) {}
    default void onProviderDisabled(String provider) {}
    default void onStatusChanged(String provider, int status, Bundle extras) {}
}

2、创建GpsLocationManager

public class GpsLocationManager {

    private static final String TAG = GpsLocationManager.class.getSimpleName();

    private final LocationManager mLocationManager;
    private LocationChangeListener mLocationChangeListener;
    private LocationChangedListener mLocationChangedListener;
    public static SpUtils mGPSSpUtils = null;

    public void setLocationChangeListener(LocationChangeListener listener) {
        this.mLocationChangeListener = listener;
    }

    public GpsLocationManager() {
        mLocationManager = (LocationManager) App.get().getSystemService(Context.LOCATION_SERVICE);
        mLocationChangedListener = new LocationChangedListener();
        mGPSSpUtils = new SpUtils(App.get(), Const.GPS_STATE_SP);
    }

    /**
     * request location.
     *
     * @param context          context
     */
    public void requestLocationUpdates(Context context) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // 如果没有位置权限,请求用户授权
            ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
        } else {
            // 如果有位置权限,开始监听位置变化
            mLocationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER,mLocationChangedListener, Looper.getMainLooper());
            mGPSSpUtils.setBoolean(Const.GPS_STATE_SP, false);
            mGPSSpUtils.apply();
        }
    }

    /**
     * release LocationManager.
     *
     */
    public void release() {
        if (mLocationManager != null && mLocationChangedListener != null) {
            try {
                mLocationManager.removeUpdates(mLocationChangedListener);
            } catch (SecurityException e) {
                Logger.e(TAG, "Error releasing location updates: " + e.getMessage());
            }
        }
    }

    public class LocationChangedListener implements LocationListener {

        public LocationChangedListener() {
        }

        @Override
        public void onLocationChanged(Location location) {
            mGPSSpUtils.setBoolean(Const.GPS_STATE_SP, true);
            mGPSSpUtils.apply();
            if (mLocationChangeListener != null) {
                mLocationChangeListener.onLocationChanged(location.getLatitude(), location.getLongitude());
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            if (mLocationChangeListener != null) {
                mLocationChangeListener.onStatusChanged(provider, status, extras);
            }
        }

        @Override
        public void onProviderEnabled(String provider) {
            mGPSSpUtils.setBoolean(Const.GPS_STATE_SP, true);
            mGPSSpUtils.apply();
            if (mLocationChangeListener != null) {
                mLocationChangeListener.onProviderEnabled(provider);
            }
        }

        @Override
        public void onProviderDisabled(String provider) {
            mGPSSpUtils.setBoolean(Const.GPS_STATE_SP, false);
            mGPSSpUtils.apply();
            if (mLocationChangeListener != null) {
                mLocationChangeListener.onProviderDisabled(provider);
            }
        }
    }
}

这里面通过SharedPreferences来存储发出位置请求及请求到位置信息等的状态。

3、在项目需求的位置调用manager中的方法去请求数据

    private static void requestLocationAndDataUpdates() {
        mGpsLocationManager.setLocationChangeListener(new LocationChangeListener() {
            @Override
            public void onLocationChanged(double latitude, double longitude) {
                Logger.d(TAG, "onLocationChanged: latitude:" + latitude + " longitude:"+ longitude);
                // 请求到位置信息,进行相应的操作
            }
        });

        // 请求位置更新
        mGpsLocationManager.requestLocationUpdates(mContext);
    }

在合适的时机,延时获取SharedPreferences的值来判断是否请求到位置信息

new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    boolean GpsMsgState = mGPSSpUtils.getBoolean(Const.GPS_STATE_SP,false);
                    Logger.d(TAG, "checkNetworkAndRequestLocation: GpsMsgState:"+GpsMsgState);
                    if (!GpsMsgState) {
                        mWeatherInfo.setGPSState(Const.GPS_INVALID);
                        // 没有请求到位置信息,进行相应的操作
                    }
                }
            }, Const.RQUEST_STATE_DELAYED_TIME);

这里面Const.RQUEST_STATE_DELAYED_TIME我定义的是6秒,一般请求到位置信息的时间大概是几秒到几十秒,可以根据具体项目进行调整。

   当然了,如果项目搭载了第三方的sdk更好,这是下下策,有弊端:如果GPS在自定义的delay时间外,那就取不到位置信息了(也可以写一个监听这个经纬度的变化的监听),如果遇到这个问题,可以参考一下。

猜你喜欢

转载自blog.csdn.net/m0_50408097/article/details/133385439