LocationListener の OnStatusChanged は Android10 で非推奨となり、Android Q 以降ではこのコールバックが呼び出されることはなく、プロバイダーは常に LocationProvider#AVAILABLE 状態であると見なされます。
次の解決策があります。
① LocationListenerCompat を使用する(GMS が搭載されているデバイスである必要があります)
② Amap SDK、Baidu 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. マネージャーのメソッドを呼び出して、プロジェクトで必要なデータを要求します。
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 がカスタム遅延時間の範囲外にある場合、位置情報を取得できないという欠点があります (また、経度と緯度の変化を監視するプログラム).監視)、この問題が発生した場合は、それを参照してください。