Android10 LocationListener's onStatusChanged is abandoned

  OnStatusChanged of LocationListener is deprecated in Android10, this callback is never called on Android Q and above, the provider can be considered to be always in LocationProvider#AVAILABLE state.

LocationListener  |  Android Developers

There are following solutions:

① Use LocationListenerCompat (the device must be equipped with GMS)

② Use Amap SDK, Baidu SDK or third party

However, in some projects, these conditions are not met, which leads to the API being abandoned. In places where the GPS signal is not good, there is no way to call back to let the application know that the GPS signal is not good and respond with logical processing. This article Focus on solving this problem.

1. Create an interface for requesting location

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. Create 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 is used to store the status of issuing location requests and requesting location information.

3. Call the method in the manager to request data where the project requires it.

    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);
    }

At the right time, delay the acquisition of the value of SharedPreferences to determine whether location information is requested.

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);

Here, I define Const.RQUEST_STATE_DELAYED_TIME as 6 seconds. Generally, the time it takes to request location information is from a few seconds to tens of seconds, and can be adjusted according to specific projects.

   Of course, it would be better if the project is equipped with a third-party SDK. This is a last resort and has drawbacks: if the GPS is outside the custom delay time, the location information cannot be obtained (you can also write a program to monitor the changes in longitude and latitude). monitoring), if you encounter this problem, you can refer to it.

Guess you like

Origin blog.csdn.net/m0_50408097/article/details/133385439