LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)不可靠,为什么?

时间:2013-05-25 09:44:22

标签: android locationmanager

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

LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

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

然后我用Google搜索并找到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

这个结果并没有让我开心。这可能有一些可能性。

  • 正如其他人质疑的那样,这个问题已经出现在某些手机上了。
  • 谷歌以4.1.2打破了这一局面。 isProviderEnabled不适用于此版本。
  • 虽然未记录,但从4.1.2开始,isProviderEnabled将无法像之前那样工作。
  • 不,Google改变了一切。这是这款手机的错误。

现在我的问题是;

  1. 对于Android 4.1.2及更高版本,LocationManager.isProviderEnabled是否仍然有效?
  2. 看到Secure.LOCATION_PROVIDERS_ALLOWED是否有一些缺点/坑洞(当我放弃使用LocationManager.isProviderEnabled?
  3. 提前致谢。

    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告诉IS时,LocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)返回false(并且确实没有)。 Android OS设计不佳吗?或者我刚刚看到的问题只与特定(但至少有两部)手机有关?

    EDIT3:

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

    我透露了2个电话名称。

    1)SBM200SH,OS4.1.2,Softbank mobile,Sharp Corporation
    2)HTX21(INFOBAR A02),OS4.1.1,KDDI,HTC

    EDIT4:

    我找到了第3部电话。

    3)SBM203SH,OS4.1.2,Softbank mobile,Sharp Corporation

    EDIT5:

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

4 个答案:

答案 0 :(得分:6)

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

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

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

  1. 某些内部状态已准备好进行网络定位。
  2. 在设置屏幕上启用了网络位置。
  3. 第二个是显而易见的。但首先不是。他们告诉我们如何模拟第一个是否定的。您可以通过以下步骤确认问题并运行我的测试应用程序(请参阅我的问题以获取下载链接)。

    • 打开手机的设置。
    • 点按应用程序。
    • 点按所有标签。
    • 找到“网络位置”,点按它。
    • 点按“停用”。
    • 重新启动手机。
    • 运行测试应用。

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

    <强>结论:

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

答案 1 :(得分:3)

检查用户位置设置的现代方法是LOCATION_MODE

中的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

答案 2 :(得分:2)

不直接回答您的问题,但请查看Google上周推出的新位置API。它实现起来非常简单,它可以检查最佳位置而不会浪费电池。 http://developer.android.com/google/play-services/location.html 这是Google I / O关于这个新API以及如何使用它的会话。 http://www.youtube.com/watch?v=Bte_GHuxUGc

这样您就不必担心检查GPS是否打开以及类似的东西

答案 3 :(得分:0)

某些手机上的位置管理器不可靠。您可能会注意到,如果您突然启动谷歌地图,您的应用程序将起作用。那是因为谷歌地图踢了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。这可能会更好,电池,准确性和可靠性。