Android onLocationChanged 不调用
Posted
技术标签:
【中文标题】Android onLocationChanged 不调用【英文标题】:Android onLocationChanged does not called 【发布时间】:2017-08-07 18:19:21 【问题描述】:我正在尝试使用 Service 和 LocationListener 在 android 中实现后台 GPS 定位服务。服务已启动(-> 调用了 onCreate 和 onStartCommand 方法),但从未调用过 onLocationChanged 方法。
这是我的服务的代码:
public class GpsHandler extends Service implements LocationListener
private static final String TAG = "GpsHandler";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
private final String LOCATION_BROADCAST_TAG = "android.LOCATION";
private final String LOCATION_EXTRA_TAG = "Location";
private Location mLastLocation = null;
@Nullable
@Override
public IBinder onBind(Intent intent)
return null;
@Override
public void onCreate()
Toast.makeText(this, "Service Started, onCreate", Toast.LENGTH_LONG).show();
@Override
public int onStartCommand(Intent intent, int flags, int startId)
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started, onStartCommand", Toast.LENGTH_LONG).show();
if (mLocationManager == null)
mLocationManager = (LocationManager)getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
mLastLocation = new Location(LocationManager.GPS_PROVIDER);
try
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, this);
catch (java.lang.SecurityException ex)
Log.i(TAG, "fail to request location update, ignore", ex);
catch (IllegalArgumentException ex)
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
return START_STICKY;
@Override
public void onDestroy()
super.onDestroy();
if (mLocationManager != null)
try
mLocationManager.removeUpdates(this);
catch (Exception ex)
Log.i(TAG, "fail to remove location listners, ignore", ex);
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
@Override
public void onProviderDisabled(String provider)
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
Toast.makeText(getBaseContext(), "Gps is turned off!! ",
Toast.LENGTH_SHORT).show();
@Override
public void onLocationChanged(Location location)
Toast.makeText(this, "Location Changed", Toast.LENGTH_LONG).show();
if(isBetterLocation(location,mLastLocation))
mLastLocation.set(location);
Intent intent = new Intent(LOCATION_BROADCAST_TAG).putExtra(LOCATION_EXTRA_TAG, location);
sendBroadcast(intent);
@Override
public void onProviderEnabled(String provider)
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
private boolean isBetterLocation(Location location, Location currentBestLocation)
if (currentBestLocation == null)
// A new location is always better than no location
return true;
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > 1000*30;//30000ms = 30 sec
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer)
return true;
// If the new location is more than two minutes older, it must be worse
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate)
return true;
else if (isNewer && !isLessAccurate)
return true;
else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider)
return true;
return false;
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2)
if (provider1 == null)
return provider2 == null;
return provider1.equals(provider2);
【问题讨论】:
我赌“请求位置更新失败,忽略” 不,这是安卓模拟器的错。现在它可以工作了。 【参考方案1】:我终于找到了解决方案。我曾尝试使用其他模拟器(最初我使用的是 Pixel C 模拟器)对其进行调试,现在它可以完美运行。所以这只是一个 Studio Bug,代码是可以工作的。我也对代码做了一点重构,去掉了一些无用的功能:
工作代码:
public class GpsHandler extends Service implements LocationListener
private static final String TAG = "GpsHandler";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 0f;
private final String LOCATION_BROADCAST_TAG = "android.LOCATION";
private final String LOCATION_EXTRA_TAG = "Location";
private Location mLastLocation = null;
@Nullable
@Override
public IBinder onBind(Intent intent)
return null;
@Override
public void onCreate()
Toast.makeText(this, "Service Started, onCreate", Toast.LENGTH_LONG).show();
@Override
public int onStartCommand(Intent intent, int flags, int startId)
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started, onStartCommand", Toast.LENGTH_LONG).show();
if (mLocationManager == null)
mLocationManager = (LocationManager)getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
mLastLocation = new Location(LocationManager.GPS_PROVIDER);
try
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, this);
mLastLocation.set(mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
catch (java.lang.SecurityException ex)
Log.i(TAG, "fail to request location update, ignore", ex);
catch (IllegalArgumentException ex)
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
return START_STICKY;
@Override
public void onDestroy()
super.onDestroy();
if (mLocationManager != null)
try
mLocationManager.removeUpdates(this);
catch (Exception ex)
Log.i(TAG, "fail to remove location listners, ignore", ex);
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
@Override
public void onProviderDisabled(String provider)
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
Toast.makeText(getBaseContext(), "Gps is turned off!! ",
Toast.LENGTH_SHORT).show();
@Override
public void onLocationChanged(Location location)
Toast.makeText(this, "Location Changed", Toast.LENGTH_LONG).show();
if(location.getAccuracy()<4*mLastLocation.getAccuracy())
mLastLocation.set(location);
Intent intent = new Intent(LOCATION_BROADCAST_TAG).putExtra(LOCATION_EXTRA_TAG, location);
sendBroadcast(intent);
@Override
public void onProviderEnabled(String provider)
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
【讨论】:
以上是关于Android onLocationChanged 不调用的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 中未调用 onlocationchanged
为啥 Android 服务中没有调用 OnlocationChanged?
Android OnlocationChanged storage