【问题标题】:Android onLocationChanged does not calledAndroid onLocationChanged 不调用
【发布时间】: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);
}

}

【问题讨论】:

  • 我赌“请求位置更新失败,忽略”
  • 不,这是安卓模拟器的错。现在它可以工作了。

标签: java android gps location android-gps


【解决方案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){}
}

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2017-01-20
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    相关资源
    最近更新 更多