Pourquoi mon OnLocationChanged () n'est jamais appelé?
Ce que je cherche à faire:
je suis en train de développer une application qui nécessite seulement l'emplacement de l'utilisateur au démarrage d'une activité. Ainsi, seulement lorsque l'utilisateur est dans l'activité, l'emplacement est mis à jour soit par le réseau ou le GPS. En conséquence, l'utilisateur peut choisir une carte intérieure.
qu'est-Ce que mon problème:
cependant, je trouve que l'application utilise toujours l'emplacement historique, et ne met jamais à jour l'emplacement. Je soupçonne il doit y avoir quelque chose de mal avec mon
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
Mais je ne sais pas où est le problème.
extrait de code associé:
Dans mon Activity
, j'ai:
locationDetector = new LocationDetector(MapSelectionActivity.this);
// try to get the current location
if (locationDetector.checkLocationServiceAvailability()) {
location = locationDetector.getLocation();
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
Log.d("MapSelectionActivity", latitude + " " + longitude);
//locationDetector.stopLocalization(); // stop the localization to save the energy
} else { // if no location service, requires the user to turn GPS on
locationDetector.showSettingsAlert();
}
Mon LocationDetector
classe est comme suit:
public final class LocationDetector implements LocationListener {
private final Context mContext;
private boolean isNetworkEnabled = false;
private boolean isGPSEnabled = false;
private boolean canGetLocation = false;
private Location location;
private String providerUsed;
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 0 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = (long) (1000 * 60 * 0.5); // 0.5 minute
// Declaring a Location Manager
protected LocationManager locationManager;
// constructor
public LocationDetector(Context context) {
this.mContext = context;
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
}
// NOTE call checkLocationServiceAvailability(); first before calling this!
public Location getLocation() {
// I SUSPECT SOMETHING IS WRONG HERE
if (isNetworkEnabled) { // use network
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("LocationDetector", "Using Network");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
providerUsed = "Network";
} else if (isGPSEnabled) { // use GPS
if (location == null) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("LocationDetector", "Using GPS");
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
}
providerUsed = "GPS";
} else { // neither the network nor the GPS is on
providerUsed = null;
Toast.makeText(mContext, "Location service is unavaliable", Toast.LENGTH_SHORT).show();
}
return location;
}
// call this to restart requesting the detecting
public void startLocalization() {
if (locationManager != null) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
}
}
// call this to stop the detecting to save power
public void stopLocalization() {
if (locationManager != null) {
locationManager.removeUpdates(LocationDetector.this);
}
}
// check location service availability
public boolean checkLocationServiceAvailability() {
// check GPS on or off
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// check Internet access
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
isNetworkEnabled = true;
} else {
isNetworkEnabled = false;
}
if (isGPSEnabled || isNetworkEnabled) {
canGetLocation = true;
} else {
canGetLocation = false;
}
return canGetLocation;
}
public String getLocationProvider() {
return providerUsed;
}
// show alert dialog to direct the users to the settings
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// make it uncancellable
alertDialog.setCancelable(false);
// Setting Dialog Title
alertDialog.setTitle("Forgot to turn GPS on?");
// Setting Dialog Message
alertDialog.setMessage("Currently there is no Internet access.nnLocalization requires GPS when Internet is unavailiable.nnDo you want to enable GPS so as to proceed?");
// On pressing Settings button
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
Toast.makeText(mContext, "After enabling GPS, press the physical 'Back' button to return", Toast.LENGTH_LONG).show();
}
});
// on pressing cancel button
alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
Toast.makeText(mContext, "No location service, please choose map manually", Toast.LENGTH_LONG).show();
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onLocationChanged(Location _location) {
// IT NEVER GETS CALLED
location = _location;
// update the text view
MapSelectionActivity.coordinatesTextView.setText("(" + Math.round(location.getLatitude() * 1000) / 1000.0 + ", " + Math.round(location.getLongitude() * 1000) / 1000.0 + ")");
// update the marker on Google Maps
MapSelectionActivity.googleMap.clear();
MapSelectionActivity.googleMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())).title("I am here!"));
MapSelectionActivity.googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15)); // 15 is the approporiate zooming level
// re-suggest the map
int recommendedMapSequenceNumber = MapSelectionActivity.mapDatabase.getMapSequenceNumber(location.getLatitude(), location.getLongitude());
MapSelectionActivity.recommendedMapTextView.setTextColor(Color.parseColor("red"));
if (recommendedMapSequenceNumber == -1) { // the so-called nearest is still too far
Toast.makeText(mContext, "Please manually select one to proceed", Toast.LENGTH_LONG).show();
MapSelectionActivity.recommendedMapTextView.setText("No recommended maps");
MapSelectionActivity.autoSelectButton.setEnabled(false);
} else { // suggest a map
Toast.makeText(mContext, "One suitable map found", Toast.LENGTH_SHORT).show();
MapSelectionActivity.recommendedMapTextView.setText(MapSelectionActivity.mapDatabase.getMapName(recommendedMapSequenceNumber));
}
Toast.makeText(mContext, "New location detected", Toast.LENGTH_SHORT).show();
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
Je ne vois jamais le Toast
onLocationChanged()
, ce qui veut dire qu'on ne l'appelle jamais!
Aussi à partir de la carte, je peux voir que la position n'est pas mise à jour.
3 réponses
comme cela semble être un problème courant avec l'obtention des emplacements Android, je vais mettre en place une liste rapide de correctifs communs:
Vérifiez votre manifeste!
L'un des problèmes les plus courants est que les bonnes permissions n'ont jamais été données. Si vous utilisez GPS (avec ou sans réseau), utilisez
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
, sinon utiliser<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
. Google FusedLocationApi nécessiteACCESS_FINE_LOCATION
.
(Pour Android 6+) vérifiez les permissions d'exécution!
Vérifiez et demandez les permissions! Si on ne vous donne jamais les permissions, vous finirez avec des accidents, ou pire (si vous attrapez toutes les exceptions), vous finirez avec aucune indication de quoi que ce soit! Peu importe que l'utilisateur vous accorde la permission au début de l'application, vérifiez toujours si vous avez les permissions pour tous les appels. Le l'utilisateur peut facilement aller à leurs paramètres et de les révoquer.
Vérifiez votre code!
Êtes-vous sûr que vous passez dans le bon auditeur? A ajouter que
BroadcastReceiver
ouIntentService
à votre manifeste? Êtes-vous à l'aide dePendingIntent.getService()
sur unBroadcastReceiver
classe, ougetBroadcast()
sur unIntentService
classe? Êtes-vous sûr de ne pas désinscrire votre auditeur ailleurs dans votre code immédiatement après une demande?
vérifier les paramètres de l'appareil!
évidemment, assurez-vous que les services de localisation sont activés.
si vous utilisez des services réseau, avez-vous activé "Scanning Always Available"? Avez-vous réglé votre mode de localisation sur "Best" ("haute précision") ou "Battery Saving" ("réseau Seulement")?
si vous utilisez le GPS, avez-vous activé "Best" ("haute précision") ou "Device only" EN mode location?
Vérifiez votre code!
Oui, c'est ici deux fois. Avez-vous essayez d'utiliser un
LocationListener
au lieu d'unPendingIntent
, ou vice-versa, pour s'assurer que vous avez réellement mis en œuvreLocationManager
correctement? Êtes-vous sûr que la demande d'emplacement n'est pas supprimée dans une partie du cycle de vie de L'activité ou du Service auquel vous ne vous attendiez pas?
Vérifiez votre environnement!
testez-vous le GPS au premier étage d'un immeuble au milieu de San Francisco? Est-ce que vous testez des sites de réseau au milieu de nulle part? Travaillez-vous dans un bunker souterrain secret, sans aucun signal radio, vous demandant pourquoi votre appareil n'est pas d'obtenir l'emplacement? Vérifiez toujours votre environnement lorsque vous tentez de résoudre des problèmes de localisation!
il pourrait y avoir beaucoup d'autres raisons moins évidentes pour lesquelles l'emplacement ne fonctionne pas, mais avant de chercher ces correctifs ésotériques, il suffit de passer en revue cette liste de contrôle rapide.
C'est vrai, vous pourriez faire face à un problème de matériel. Veuillez installer sur l'appareil L'État de L'application :GPS afin de voir si votre GPS fonctionne correctement!
locationManager.requestlocationsupdates (LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Pour cette ligne
MIN_DISTANCE_CHANGE_FOR_UPDATES = 0 mètre.
MIN_TIME_BW_UPDATES = 1000 secondes.
pour en venir à votre question, onLocationChanged () sera appelé si la mise à jour de l'emplacement actuel ne correspond pas au dernier emplacement connu.
La mise à jour l'emplacement sera changé pour chaque minTime (dans mon cas 1000 milli sec) et aussi si l'appareil a bougé distance de l'esprit (dans mon cas 0 mètres).
j'espère que vous le comprendrez.