【问题标题】:LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) is not reliable, why?LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) 不可靠,为什么?
【发布时间】:2013-05-25 09:44:22
【问题描述】:

我的应用程序的一位用户报告说,应用程序告诉网络位置已关闭,即使他确实打开了它。他给我发了几个屏幕截图,它们让我思考;

LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

工作不正常。他的手机运行的是 Android 4.1.2,首先我认为this 是导致此问题的原因。但事实并非如此。他也给我发了那个设置的屏幕截图。

然后我用谷歌搜索并找到this。这个问题似乎对我有帮助,但不幸的是,答案对这个案例没有帮助,提问者没有进一步追问。

我的应用程序与位置相关,并且一直在使用 LocationManager.isProviderEnabled 来了解 GPS 和网络位置的打开或关闭。直到最近,我才被告知我的应用程序没有正确了解这些设置。他是第一个报告此问题的用户。通过查看 Secure.LOCATION_PROVIDERS_ALLOWED,我了解到还有另一种方法可以了解 GPS 和网络的位置设置。为了看看这个方法在他的手机上是如何工作的,我写了一个简单的应用程序并让他运行。这个应用程序执行简单的任务并在屏幕上显示文本。

LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
    string = "GPS=on\n";
}
else
{
    string = "GPS=off\n";
}
if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
    string += "Network=on\n";
}
else
{
    string += "Network=off\n";
}
String status = android.provider.Settings.Secure.getString(getContentResolver(), Secure.LOCATION_PROVIDERS_ALLOWED);
if(status.contains("gps"))
{
    string += "GPS=on\n";
}
else
{
    string += "GPS=off\n";
}
if(status.contains("network"))
{
    string += "Network=on\n";
}
else
{
    string += "Network=off\n";
}

他又发回了屏幕截图。看起来;

GPS=on
Network=off
GPS=on
Network=on

这个结果并没有让我高兴。这可能有一些可能性。

  • 正如其他人之前所质疑的那样,这个问题在一些手机上已经存在。
  • Google 用 4.1.2 打破了这一点。 isProviderEnabled 不适用于此版本。
  • 虽然没有记录,但从 4.1.2 开始,isProviderEnabled 将无法像以前那样工作。
  • 不,Google 改变了一切。这是此特定手机的错误。

现在我的问题是;

  1. Lo​​cationManager.isProviderEnabled 对 Android 4.1.2 及更高版本仍然有效吗?
  2. 看到 Secure.LOCATION_PROVIDERS_ALLOWED 是否有一些缺点/坑洞(当我放弃使用 LocationManager.isProviderEnabled 时?

提前致谢。

EDIT1:

Here您可以从 Google Play 下载测试应用进行尝试或请人尝试。

EDIT6:

自从回答了这个问题后,我删除了测试应用。

EDIT2:

我发布了我的应用程序,该应用程序通过查看 Secure.LOCATION_PROVIDERS_ALLOWED 来检查网络提供商是否可用,并在有限的手机上出现异常。 这些是 ACRA 的报告。

一些运行 OS 4.1.1 的手机。

java.lang.IllegalArgumentException: requested provider network doesn't exisit
    at android.os.Parcel.readException(Parcel.java:1434)
    at android.os.Parcel.readException(Parcel.java:1384)
    at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:675)
    at android.location.LocationManager._requestLocationUpdates(LocationManager.java:686)
    at android.location.LocationManager.requestLocationUpdates(LocationManager.java:508)

一些运行 OS 4.1.2 的手机。

java.lang.IllegalArgumentException: provider=network
    at android.os.Parcel.readException(Parcel.java:1439)
    at android.os.Parcel.readException(Parcel.java:1389)
    at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:659)
    at android.location.LocationManager._requestLocationUpdates(LocationManager.java:690)
    at android.location.LocationManager.requestLocationUpdates(LocationManager.java:512)

在我更改了一种方法来检查网络提供商的位置是否可用之前,我从未见过这些异常。所以我认为 LocationManager.isProviderEnabled 是安全的,看到 Secure.LOCATION_PROVIDERS_ALLOWED 是有风险的。但这会让我回到原来的问题。为什么当 Secure.LOCATION_PROVIDERS_ALLOWED 告诉存在时 LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) 返回 false(实际上并没有)。 Android 操作系统是否设计不佳?还是我刚刚看到仅与特定(但至少有 2 个)手机相关的问题?

EDIT3:

我更新了测试应用,通过 requestLocationUpdates() 访问显示 GPS/网络位置提供程序是否真的可用。

我透露了 2 部手机的名字。

1) SBM200SH、OS4.1.2、软银手机、夏普公司
2) HTX21 (INFOBAR A02), OS4.1.1, KDDI, HTC

EDIT4:

我找到了第三部手机。

3) SBM203SH、OS4.1.2、软银手机、夏普公司

EDIT5:

Sharp Corporation 正在为移动开发者提供讨论空间。我通过提出这个 SO 的问题来发布主题。我希望夏普公司有人为此采取行动。我会保持更新。

【问题讨论】:

  • 我刚刚在 4.1.2 (galaxy s2) 和 4.2.2 (nexus 7) 上测试了它,在两种设备上都可以正常工作。只有这个用户吗?他用什么手机?
  • 只是一个评论,但考虑使用 fused。
  • @dumazy,我看到至少有 2 部手机有这个问题。而且我现在不愿意显示手机的名称。
  • @Tomcat,已知三星手机存在网络提供商位置问题。为电话命名,以便为您提供帮助。
  • 请查看已编辑的问题。

标签: android locationmanager


【解决方案1】:

夏普公司提供的开发人员支持非常出色,他们在不到 48 小时内就回答了我的问题。

这是我从他们那里得到的。

LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) 返回 true 必须满足 2 个条件。

  1. 某些内部状态已准备好进行网络定位。
  2. 网络位置已在设置屏幕上启用。

第二个很明显。但第一个不是。他们告诉如何模拟第一个是否定的。您可以通过以下步骤确认问题并运行我的测试应用(请参阅我的问题以获取下载链接)。

  • 打开手机设置。
  • 点击应用程序。
  • 点按所有选项卡。
  • 找到“网络位置”,点击它。
  • 点按“禁用”。
  • 重启手机。
  • 运行测试应用。

由于我无法理解用户的手机未能执行与上述第一个条件相关的操作并出现问题。

结论:

LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) 是可靠的。请注意,Secure.LOCATION_PROVIDERS_ALLOWED 不太可靠。

【讨论】:

  • 您的客户会执行所有这些步骤吗?您是否在其他手机上测试过您的应用程序?三星 2.3.6 和 4.0 ?在我看来,您需要以编程方式触发更新。想想吧。
  • 一位用户使用了我的测试应用程序并证明了导致此问题的原因。我的回答可能听起来不对,因为您无法阅读夏普公司运营的用户支持论坛上的对话。他们清楚地指出了问题,并且已经解决了。
【解决方案2】:

检查用户位置设置的现代方法是通过LOCATION_MODE in Settings.Secure

例如,如果您只是想知道用户是否禁用了它们,您可以这样做:

   public static boolean isLocationEnabled(Context context) {
       return getLocationMode(context) != Settings.Secure.LOCATION_MODE_OFF;
   }

   private static int getLocationMode(Context context) {
       return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
   }

如果启用了位置,这将返回 true。如果您需要更精细的粒度see the docs 了解详情。

与旧的 NETWORK_PROVIDER 和 GPS_PROVIDER 方法相比,此方法更适合使用 Google 服务位置 API。注意:需要 KitKat / API19

【讨论】:

  • 这也被弃用了。要检查位置状态,请使用 LocationManager#isLocationEnabled()。要获取位置提供者的状态,请使用 LocationManager#isProviderEnabled(String)。
【解决方案3】:

不直接回答您的问题,但请查看 Google 上周推出的新 Location API。这真的很容易实施,它会在不浪费电池的情况下检查最佳位置。 http://developer.android.com/google/play-services/location.html 这是 Google I/O 上关于这个新 API 以及如何使用它的会议。 http://www.youtube.com/watch?v=Bte_GHuxUGc

这样您就不必担心检查 GPS 是否开启之类的事情

【讨论】:

  • 这个答案与我的问题无关。
【解决方案4】:

位置管理器在某些手机上不可靠。您可能会注意到,如果您突然启动 google 地图,您的应用程序可以正常工作。那是因为谷歌地图踢了 LocationManager。这也意味着有一种程序化的方式可以活活踢那个家伙。所以我用了

HomeScreen.getLocationManager().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) {
        }
    });

在上面的代码之后,我从 LocationManager 调用了我需要的任何东西,它有点工作。如果不尝试新的 API 的 LocationClient。这在电池、准确性和可靠性方面应该要好得多。

【讨论】:

  • 调用 requestLocationUpdates 抛出异常。请再次查看问题。我想我面临的问题与你所知道的不同。
  • @Tomcat 你可能是对的,但我也应该注意,在某些情况下,上面的解决方案就像一个魅力。
猜你喜欢
  • 2016-03-22
  • 2010-09-10
  • 2011-05-20
  • 2014-12-25
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
相关资源
最近更新 更多