LocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) 在 Galaxy S7 上总是返回 NULL(仅限)
Posted
技术标签:
【中文标题】LocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) 在 Galaxy S7 上总是返回 NULL(仅限)【英文标题】:LocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) always returns NULL on Galaxy S7 (ONLY) 【发布时间】:2016-03-15 17:59:41 【问题描述】:刚收到运行 Marshmallow (6.0.1) 的 Galaxy S7 (Edge),发现我的应用程序存在问题,该应用程序使用 android.permission.ACCESS_COARSE_LOCATION
并针对 Sdk 版本 22 (Lollipop)。当我调用locationManager.getLastKnownLocation()
时,它总是返回NULL。这是我正在运行的内容:
public Location getLastKnownLocationObject(Context context)
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// Location is always null on S7 (only)
Log.i(TAG, ">>> getLastKnownLocationObject() getLastKnownLocation: " + location);
return location;
catch (Exception e)
Log.e(TAG, ">>> getLastKnownLocationObject() exception", e);
return null;
同样的代码在我尝试过的所有其他设备上都能正常工作:Galaxy S5 (5.0.1)、Nexus 7 (5.0.1)、Nexus 9 (6.0.1) 和 Samsung Tab3 (4.4.2)
请注意,如果我将清单更改为使用 ACCESS_FINE_LOCATION,上述代码在每个设备上都可以正常工作。很遗憾,管理层目前不允许我更改权限。
在我在这里看到的一些答案中,建议在执行 getLastKnownLocation() 之前调用以下命令,但这没有任何效果。
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener()
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
@Override
public void onProviderEnabled(String provider)
@Override
public void onProviderDisabled(String provider)
@Override
public void onLocationChanged(final Location location)
// NEVER CALLED on Samsung S7 for LocationManager.NETWORK_PROVIDER
);
所以目前,我觉得这是新三星 Galaxy S7 独有的问题。
【问题讨论】:
自从 Marshmallow 引入运行时权限模型以来,您是否尝试过以编程方式请求权限? 我的应用程序目标是 22(棒棒糖)。 minSdkVersion 19 目标SdkVersion 22 您必须专门请求 Android Marshmallow 及更高版本的权限。检查我的这篇文章 - ***.com/questions/35856432/… 感谢 Shadab...您的帖子显示 GPS_PROVIDER,如果我将清单权限更改为 ACCESS_FINE_LOCATION,它可以很好地与我的代码一起使用并且无需请求权限(我的目标是 Lollipop)。 请改用 Fused Location Provider api,可用于 Google Play 服务框架。这可能会有所帮助。 【参考方案1】:根据我使用三星设备的经验。如果您重新启动手机并且不启用 GPS,您将无法获得位置。如果您启用 GPS 作为某个点 - 也许通过运行谷歌地图,那么您将获得一个位置。三星不会返回 GPS、网络或无源提供商的位置,除非它在设备开机循环期间获得了位置。
我在代码中进行的任何调用都没有让它启动并激活并获取位置。它们在其他设备上运行良好。三星似乎也不会将这些信息缓存很长时间。
【讨论】:
【参考方案2】:好吧,你打电话给isProviderEnabled()
,所以至少已经涵盖了,并且应该启用使用网络位置。但是documentation 的确切措辞是:
"如果用户在设置菜单中启用了此提供程序,则 true 为 否则返回false”
所以这只是提供者被“启用”而不是被用户关闭。
有问题的手机(S7)里面有 SIM 卡吗?在该特定设备上,基于网络的定位可能需要 SIM 卡或互联网连接。
参考documentation,您可以查看这些返回的内容:
locationManager.getProvider(LocationManager.NETWORK_PROVIDER).requiresCell();
locationManager.getProvider(LocationManager.NETWORK_PROVIDER).requiresNetwork();
当然,如果位置未知,只需调用getLastKnownLocation()
将返回null
。并且不知道是否没有应用程序(您的或其他应用程序)专门要求设备确定其位置。因此,致电requestLocationUpdates()
的建议是正确的建议。但确定位置可能需要一段时间,因此在之后调用getLastKnownLocation()
可能仍会返回null
。
即使它返回一些东西,它也可能是非常旧的数据,甚至不再有效。那么为什么不只是subscribe to receive location updates?这就是它的意图。您正在使用基于网络的定位,因此它不会(完全/显着)影响功耗,并且如果您指定适合您需要的时间间隔和距离限制,更新也不会过于频繁。
【讨论】:
感谢您的帮助...我现在可以测试 2 款不同的 Galaxy S7,它们都是可上网的功能齐全的手机(并且在两个不同的运营商上,而不是那意味着什么)。使用其他应用程序获取 GPS 坐标没有问题。请注意,如果我将权限更改为 ACCESS_FINE_LOCATION 没有任何问题。我确实尝试了 .requiresCell() 和 .requiresNetwork() ,有趣的是,它们在 S7 上都返回 True,但在我测试的所有其他设备上,这两个调用都返回 false。 (我不需要订阅更新,因为我只需要一个天气应用的大致位置) 您当然可以在onLocationChanged()
回调中收到最新的位置后致电removeUpdates()
,然后您将不会收到进一步的更新。这将是 getLastKnownLocation()
返回 null 的情况的解决方案。
实际上,我们的代码会按照您的建议进行操作,并且如果最后一个已知位置恰好为空(直到 S7,我们才真正看到),它会请求位置更新。我看到的问题是,从 NETWORK_PROVIDER 请求位置时,S7 上永远不会触发 onLocationChanged()。 locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener);
这是 ACCESS_COARSE_LOCATION 的清单权限。如果我将其更改为 ACCESS_FINE_LOCATION,该代码将按预期工作。以上是关于LocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) 在 Galaxy S7 上总是返回 NULL(仅限)的主要内容,如果未能解决你的问题,请参考以下文章