Android onLocationChanged没有调用

时间:2017-03-16 14:07:17

标签: java android gps location android-gps

我正在尝试使用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 个答案:

答案 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){}
}