我正在尝试使用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);
}
}
答案 0 :(得分:0)
最后我找到了解决方案。我试图用另一个模拟器调试它(最初我使用过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){}
}