Android 为什么我的OnLocationChanged()从未被调用?
我想做什么: 我正在尝试开发一个只需要在一个活动开始时提供用户位置的应用程序。因此,只有当用户在活动中时,位置才能通过网络或GPS进行更新。因此,用户可以选择室内地图 我的问题是什么:Android 为什么我的OnLocationChanged()从未被调用?,android,android-location,android-loadermanager,Android,Android Location,Android Loadermanager,我想做什么: 我正在尝试开发一个只需要在一个活动开始时提供用户位置的应用程序。因此,只有当用户在活动中时,位置才能通过网络或GPS进行更新。因此,用户可以选择室内地图 我的问题是什么: public final class LocationDetector implements LocationListener { private final Context mContext; private boolean isNetworkEnabled = false; pri
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.\n\nLocalization requires GPS when Internet is unavailiable.\n\nDo 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) {
}
}
但是,我发现应用程序总是使用历史位置,并且从不更新位置。我怀疑我的电脑一定出了问题
location=locationManager.getLastKnownLocation(locationManager.NETWORK\u提供程序)
但我不确定问题出在哪里
相关代码片段:
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.\n\nLocalization requires GPS when Internet is unavailiable.\n\nDo 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) {
}
}
在我的活动中
,我有:
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();
}
MyLocationDetector
类如下:
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.\n\nLocalization requires GPS when Internet is unavailiable.\n\nDo 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) {
}
}
我从未在onLocationChanged()
中看到过Toast
,这意味着它从未被调用过!
同样从地图上,我可以看到位置没有更新。没错,您可能会面临硬件问题。请在设备上安装App:GPS STATUS,以查看您的GPS是否正常工作 locationManager.RequestLocationUpdate (LocationManager.GPS\u提供程序、最短时间更新、最短距离更新、最短距离更新)强> 这条线 更新的最小距离更改=0米 最短时间更新=1000秒 关于您的问题,如果当前位置更新与上次已知位置不匹配,将调用onLocationChanged() 更新的位置将每分钟更改一次(在我的情况下为1000毫秒),并且如果设备移动了minDistance(在我的情况下为0米)距离,也会更改
我希望你能理解这一点。因为这似乎是获取Android位置的常见问题,我将列出一个常见修复的快速清单:
,否则请使用
。谷歌的FusedLocationApi需要访问\u FINE\u位置
BroadcastReceiver
或IntentService
添加到您的清单中?您是在BroadcastReceiver
类上使用pendingent.getService()
,还是在IntentService
类上使用getBroadcast()
?您确定没有在请求后立即在代码的其他地方注销侦听器吗LocationListener
而不是PendingEvent
,或者反过来使用LocationManager
,以确保实际正确实施LocationManager?您确定在活动或服务生命周期的某些部分中没有删除位置请求,而这是您不希望发生的吗
可能还有许多其他不太明显的原因导致定位不起作用,但在搜索那些深奥的修复方法之前,只需浏览一下这个快速检查表。
(1000*60*0.5)
这实际上是30秒,您需要将其更改为(1000*60*5)
,间隔5分钟,然而,这不是实际问题。您在清单中授予了足够的权限吗?@Vigbyor-我猜这5分钟是关于GPS\u提供程序的
,因为它们对于网络\u提供程序
?好的,现在评论此代码如果(locationManager!=null){location=locationManager.getLastKnownLocation(locationManager.NETWORK_PROVIDER);}
并再次尝试执行您的代码。@perfectionm1ng-您可能会得到GPS\u提供程序刷新的位置,但由于您给它30秒的刷新时间,所以这永远都不够,这就是为什么它不刷新它。另一方面,您是getLastKnownLocation(LocationManager.NETWORK\u提供程序)
,它永远不会刷新,因为首选的提供商是GPS-对吗?