OnLocationChanged 回调永远不会被调用
我正在尝试使用 LocationManager
获取用户当前位置。我做了很多研究,似乎找不到任何人有同样的问题。 OnLocationChanged
回调似乎从未被调用。下面是我的各种代码和 logcat。
protected LocationListener locationListener;
protected LocationManager locationManager;
protected Context context;
我的 OnCreate()
方法
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "IN ON CREATE");
this.context = getActivity();
registerLocationUpdates();
}
我的 registerLocationUpdates
方法
void registerLocationUpdates() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_LOW);
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE);
provider = locationManager.getBestProvider(criteria, true);
// Cant get a hold of provider
if (provider == null) {
Log.v(TAG, "Provider is null");
showNoProvider();
return;
} else {
Log.v(TAG, "Provider: " + provider);
}
locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(provider, 1L, 1f, locationListener);
// connect to the GPS location service
Location oldLocation = locationManager.getLastKnownLocation(provider);
if (oldLocation != null) {
Log.v(TAG, "Got Old location");
latitude = Double.toString(oldLocation.getLatitude());
longitude = Double.toString(oldLocation.getLongitude());
waitingForLocationUpdate = false;
getNearbyStores();
} else {
Log.v(TAG, "NO Last Location found");
}
}
我的 LocationListener
private class MyLocationListener implements LocationListener {
public void onLocationChanged(Location location) {
latitude = Double.toString(location.getLatitude());
longitude = Double.toString(location.getLongitude());
Log.v(TAG, "IN ON LOCATION CHANGE");
if (waitingForLocationUpdate) {
getNearbyStores();
waitingForLocationUpdate = false;
}
locationManager.removeUpdates(this);
}
public void onStatusChanged(String s, int i, Bundle bundle) {
Log.v(TAG, "Status changed: " + s);
}
public void onProviderEnabled(String s) {
Log.e(TAG, "PROVIDER DISABLED: " + s);
}
public void onProviderDisabled(String s) {
Log.e(TAG, "PROVIDER DISABLED: " + s);
}
}
我在 AndroidManifest 中的权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
最后是我运行应用程序后的 logcat
01-25 09:43:10.963: VERBOSE/NearbyListFragment(3060): IN ON CREATE
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.973: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): Provider: gps
01-25 09:43:10.983: DEBUG/LocationManager(3060): requestLocationUpdates: provider = gps, listener = co.fusionweb.dealsplus.app.NearbyItems$NearbyListFragment$MyLocationListener@46ef4680
01-25 09:43:10.983: DEBUG/GpsLocationProvider(1329): setMinTime 1
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): NO Last Location found
01-25 09:43:10.983: VERBOSE/LocationManagerService(1329): _requestLocationUpdates: listener = Receiver{47421e68 Listener android.os.BinderProxy@47421a68}
01-25 09:43:11.003: VERBOSE/countingFragment(3060): IN ON CREATE VIEW
01-25 09:43:11.003: WARN/GpsLocationProvider(1329): Duplicate add listener for co.fusionweb.dealsplus
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): In Constructor
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): Scrolling
01-25 09:43:11.033: DEBUG/GpsLocationProvider(1329): startNavigating
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_time_out(standalone = 60, agps = 89)
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_accuracy(accuracy = 50)
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): persist.radio.agps.mode: []
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_position mode, client = 1, interval = 1, mode = 1
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl called: client = 1, ioctl_type = 2
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_ioctl
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [96]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_api_sync_ioctl: select_id = 0, loc_ioctl returned 0
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): Callback received: 80 (cb_id=0x5310000 handle=1)
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl result: client = 1, ioctl_type = 2, SUCCESS
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_start
01-25 09:43:11.043: DEBUG/locapi_rpc_glue(1329): loc_start_fix
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [44]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.053: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.113: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.113: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_SESSION_BEGIN
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.113: VERBOSE/GpsLocationProvider(1329): reportStatus status: 1
01-25 09:43:11.113: DEBUG/GpsLocationProvider(1329): Acquiring wakelock
01-25 09:43:11.123: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.183: DEBUG/PowerManagerService(1329): New lightsensor value:40, lcdValue:77
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.273: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.273: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_ENGINE_ON
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.273: VERBOSE/GpsLocationProvider(1329): reportStatus status: 3
以及 android SDK 位置logcat 的某些部分不断重复。我已经尝试了所有我能想到的以及在 google 和 stackoverflow 上看到的东西。另外,作为旁注,我已经能够使用 API 9 中提供的 requestSingleUpdate
并按照指南 深入了解位置,但我需要它来工作使用旧 SDK 的 2.1 或 2.2 及更高版本。因此,如果您有任何提示或想了解更多信息,请告诉我。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
看来您的设置应该有效,因为它不起作用,我会让您的示例尽可能简单以便进行故障排除。我会让你的请求看起来像
这样你就可以获得所有可能的更新。并注释掉有关获取最后已知位置的部分。目前还不需要。
然后在
onLocationChanged()
中,只需注释掉其余部分,以便让侦听器保持活动状态。这应该会为您提供真实设备上的更新流。在模拟器上,您需要使用 DDMS,并且每次按发送键时您都会收到一次 GPS 更新。
It looks like you setup should work, since it doesn't, I would make your example as simple as possible in order to troubleshoot. I would make your request look like
This way you get ALL the updates possible. And comment out the part about getting the last known location. It's not needed yet.
Then in
onLocationChanged()
, just haveComment out the rest so that you keep your listener active. This should give you a stream of updates on a real device. On the emulator, you'll need to use DDMS, and you'll get one GPS update each time you press send.
更换
与
解决了我的问题。
这是我的位置管理器的代码片段
//检查位置权限、Marshmallow 及以上
//获取当前位置
// 使用 LocationManager.NETWORK_PROVIDER 请求位置更新
Replacing
with
solved my problem.
Here is code snippet of my location manager
//Check for Location permissions, Marshmallow and above
//Get current location to start with
// Request location update using LocationManager.NETWORK_PROVIDER
当设备处于低电量或使用省电模式时,GPS 提供商将禁用,那么在这种情况下,我们无法接收
onLocationChanged
GPS 提供商几乎不会返回如果您留在房屋或建筑物内,则位置(仅在室外工作良好)
因此,在我的应用程序中,我将使用
GPS_PROVIDER
和NETWORK_PROVIDER
来接收onLocationChanged()< /代码>更好
https://developer.android.com/guide/topics/location/策略.html#更新
GPS Provider will disable when device in low power or use power save mode then in that case we can not receive
onLocationChanged
GPS Provider hardly ever return the location if you stay inside house or building (only work well in outdoor)
Therefore, in my app I will use both
GPS_PROVIDER
andNETWORK_PROVIDER
to receiveonLocationChanged()
betterhttps://developer.android.com/guide/topics/location/strategies.html#Updates
正如史蒂夫·布莱克威尔(Steve Blackwell)所写,你的设置很好。您可以尝试了解自己是否 100% 有 GPS 固定信号!我已经安装了一个不错的 GPS 测试器应用程序(来自 Play 商店)< /a> 它将显示您是否已修复、您连接到哪些卫星以及连接强度是多少。
这就是我的 OnLocationChanged() 从未调用的原因。我尝试从建筑物内运行它:\
祝你好运!
As Steve Blackwell wrote, your setup is good. What you can try is to understand if you 100% have a GPS fixed signal! I have installed a nice GPS Tester application (from the play store) and it will show you if you have a fix or not and to which satellites you are connected and what is the connection strength.
This was the reason my OnLocationChanged() never called.. I tried running it from within a building :\
good luck!
很抱歉撞到这么旧的线程,但这可能对其他人来说很方便,因为这个问题在谷歌搜索上排名相对较高。
我遇到了类似的问题,onlocationchanged 没有被解雇,但我找不到我的代码有任何问题。在尝试了各种组合之后,我意识到问题的根本原因是我在服务中注册了监听器。
该服务是前台服务,因此基于 Google 文档这应该有效,但没有!
将初始化包装在一个方法中,然后从创建或绑定到服务的活动中调用该方法解决了我的问题。
这是我在服务中的方法:
如果我从服务本身内部调用它,我将不会收到任何位置更新(再次注意服务是前台服务,它实际上绑定到当前正在运行的活动)。
但是,如果我从创建/绑定到服务的活动中调用此方法,如下所示,它可以正常工作:
希望这可以帮助其他遇到此问题的人。
Sorry for bumping such an old thread, but this might come handy to some others, since this question is ranking relatively high on google search.
I had a similar problem, the onlocationchanged wasn't getting fired, but I could not find anything wrong with my code. After trying all sorts of combination, I realised that the root cause of the problem was the fact that I was registering the listener in a service.
The service WAS a foreground service, so based on Google documentation that should work, it DID NOT!
Wrapping the initialisation in a method, and calling the method from the activity which created or bind to the service solved my problem.
This is my method in my service:
If I call this from within the Service itself I won't receive any Location Updates (again note service is a FOREGROUND service and it's actually binded to an activity which is currently running).
However if I call this method from the activity which created/bound to the service like below it works fine:
Hope this helps some others who come across this problem.
我遇到过类似的问题。我有权限,正确请求服务,但没有更新。事实证明,我所要做的只是等待。当我在互联网上搜索问题时,我运行了应用程序,几分钟后它就开始接收更新。然后,即使当我杀死应用程序并再次运行它时,更新也会立即出现 - 我猜这是一个系统问题,进行了一些优化,可能是因为设备根本没有移动(顺便说一句。这不是一些糟糕的设备,它是像素)。
I experienced similar issue. I had the permissions, requested for service correctly, but no update came. It turned out that all I had to do was simply wait. While I was searching for the issue on the internet, I had the application running and after few minutes it just started to receiving updates. Then even when I killed the app and run it again, the updates came instantaneously - I guess it is a system thing, some optimization, maybe due to the fact that device wasn't moving at all (btw. it is not some shitty device, it is Pixel).
我遇到了同样的问题。我得到的 getLastKnownLocation 为空。当我重新启动设备和设备中的位置服务时,问题得到解决。
I faced same issue. I was getting getLastKnownLocation as null. Issue is resolved when I restarted both the device and Location service in device.
如果您尝试使用 NETWORK_PROVIDER,那么测试确实很困难:
我想原因是它只是网络提供商的位置而不是您的设备本身,并且网络提供商永远不会移动,因此 onLocationChanged() 永远不会调用。仅当在移动数据和 WiFi 之间切换时才可能发生这种情况,反之亦然。如果我错了,请纠正我。
所以我建议先使用GPS_PROVIDER进行实验,然后再考虑性能和电池使用情况。它在模拟器和真实设备上都能很好地工作。最佳实践:https://developer.android.com/guide/topics /location/strategies.html
我花了几个小时使用 NETWORK_PROVIDER 进行测试,但没有任何结果,所以希望我的建议有所帮助。
If you are trying with NETWORK_PROVIDER, it is really difficult to test:
I guess the reason is that it just the location of network provider only not your device itself, and the network provider never move, so the onLocationChanged() never call. It might happen only when switching between mobile data and wifi and vice versa. Please correct me if I am wrong.
So I suggest to use GPS_PROVIDER to experiment before considering performance and battery usage. It works nicely on both emulators and real devices. For the best practice: https://developer.android.com/guide/topics/location/strategies.html
It took me several hours to test with NETWORK_PROVIDER without any results, so hopefully my suggestion helpful.
我在我的真实设备(M,应用程序的 targetSDK 23)上遇到了同样的问题(onLocationChanged() 从未使用 NETWORK_PROVIDER 调用),直到我重新启动它。
I had the same problem (onLocationChanged() never called with NETWORK_PROVIDER) on my real device (M, app's targetSDK 23) until I restarted it.
正如
Phan Van Linh
回答的那样,这可能是因为您在建筑物内。此处有关于如何为模拟器模拟 GPS 的说明。
此外,还有此应用模拟 GPS 数据。
As
Phan Van Linh
answered , it's probably because you are inside a building.There are explanation here on how to mock GPS for the emulator.
Also, there is this app that mocks GPS data.
我有 2 台设备:Samsung Galaxy S4 (Android 5.0.1) 和 Vertex Win (Android 8.1)。
在三星上,一切正常且快速,找到 GPS 坐标,并调用
onLocationChanged
。在优先级
PRIORITY_BALANCED_POWER_ACCURACY
的 Vertex 上,它可能首先与网络提供商交互,因此它通过 Wi-Fi 查找坐标。但它无法正确检测位置服务是否打开(一段时间后设备认为它已打开,而实际上它已关闭,并调用LocationServices.getSettingsClient< 的
addOnSuccessListener
方法/code> 因此,我切换到了 PRIORITY_HIGH_ACCURACY 并得到了另一个惊喜,网络提供商已关闭,但没有调用 onLocationChanged,所以我 在建筑物内也无法接收到信号。无法获取坐标。我从 Play Market 下载了 GPS 测试仪(按照 @Li3ro 的建议),发现卫星是可见的,但即使 独立地图无法接收坐标,但户外可以。因此,在我离开后,我可以在应用程序中找到我的坐标
。 href="https://stackoverflow.com/a/27828929/2914140">https://stackoverflow.com/a/27828929/2914140,其中提到了优先级和错误识别(经过一段时间后禁用 GPS)如果没有找到坐标,则为时间)。
I have 2 devices: Samsung Galaxy S4 (Android 5.0.1) and Vertex Win (Android 8.1).
On Samsung everything works right and fast, GPS coordinates are found, and
onLocationChanged
is called.On Vertex in prioity
PRIORITY_BALANCED_POWER_ACCURACY
it probably interacts with network provider first, so it finds coordinates via Wi-Fi. But it can't detect right, whether location service is turned on (after some time the device thinks it is turned on, while it is off, and callsaddOnSuccessListener
method ofLocationServices.getSettingsClient
. So I switched toPRIORITY_HIGH_ACCURACY
and got another surprise. Network provider turned off, butonLocationChanged
wasn't called, so I couldn't get coordinates. I downloadedGPS tester
(as @Li3ro advised) from Play Market and saw that sattelites are visible, but without fixed signal. I couldn't receive a signal inside a building.Even standalone maps couldn't receive coordinates, but outdoor could. So, after I walked away, I could find my coordindinates in an application.
See also https://stackoverflow.com/a/27828929/2914140, where it is said about priorities and error recognition (disabling GPS after some time if no coordinsates found).
这应该是由于您的手机设置而发生的。在手机位置设置中,如果位置服务模式设置为仅 GPS,则 OnLocationChanged 回调会在有 GPS Fix 时调用。通过选择“使用 GPS、WI-FI 和移动网络”选项,将使用这三个提供商来确定位置。这将花费更少的时间来定位您的设备位置。
***访问位置服务的路径可以更改设备。
谢谢
This should be happen due to your phone settings. In phones Location settings, If the Location service Mode set to GPS only, then OnLocationChanged callback calls when there is GPS Fix. By selecting Use GPS, WI-FI And mobile networks options, location will be determine by using those three providers. This will take less time to locate your device location.
***Path to access to location services could be change device to device.
Thanks
当位置关闭时,这发生在我身上。不是应用程序的位置权限,而是 Android 设备本身的位置。请求用户激活 GPS 为我解决了这个问题:
来自 此处。
您可能还需要关闭 GPS,然后再次打开以触发对话框以提高位置准确性:
This happened to me when the location was turned off. Not the location permission for the app, but the location for the android device itself. Requesting that the user activate the GPS fixed it for me:
Solution from here.
You may also need to turn the GPS off and then on again to trigger a dialog to improve location accuracy:
就我而言,即使编写了正确的代码,我也没有使用 client.requestLocationUpdates(locationRequest, this, it) 获取位置。
在手机中也启用了 GPS,
在花费时间切换模拟器、构建等之后,最终发现位置模式是“仅设备”,并且它没有在模拟器上提供结果。将其切换到“高精度”并开始工作。
In my case even after writing correct code, I did not get location using
client.requestLocationUpdates(locationRequest, this, it)
.In phone gps was enabled as well using
After spending time in switching emulators, builds, etc, finally figured out that Location mode was "Device Only" and it wasn't providing the result on emulator. Switched to it to "High accuracy" and it started working.
就我而言,GPS 被禁用。
所以我从设置中打开位置,效果很好
In my case the gps was disabled.
So I turned On Location from setting and it worked fine