2017-03-16 65 views
-1

我想在android中使用Service和LocationListener实现背景GPS定位服务。服务开始( - >调用onCreate和onStartCommand方法),但onLocationChanged方法从不调用。Android 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

我打赌“失败请求位置更新,忽略“ – Selvin

+0

不,它是Android模拟器的错。现在它可以工作。 –

回答

0

最后,我已经找到了解决办法。我试图用其他模拟器进行调试(原来我使用的是Pixel C模拟器),现在它工作起来完美无瑕。所以,这只是一个工作室的Bug,代码working.I也重组一下代码,删除一些无用的功能:

工作代码:

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