【问题标题】:How to check for Mock Location in Android Marshmallow?如何在 Android Marshmallow 中检查模拟位置?
【发布时间】:2015-12-16 13:48:47
【问题描述】:

如何在AndroidMarshmallow中检测位置是否被Mock Location触发?

之前我用Settings.Secure.ALLOW_MOCK_LOCATION

但是,在 API 级别 23 中,这已被弃用。

我想检查触发器是假定位还是原始 GPS?

现在,检查Mock Location 是否启用Android Marshmallow 的替代方法是什么?

【问题讨论】:

    标签: android location geofencing android-6.0-marshmallow


    【解决方案1】:

    如果您使用FusedLocationProviderApi 并在回调/pendingIntentCallback 中使用setMockLocation(mGoogleApiClient, fakeLocation); 设置模拟位置,则返回的Location 对象包含额外的KEY_MOCK_LOCATION,一个指示接收到的对象是模拟的布尔值。

    @Override
    
    public void onLocationChanged (Location location){    
       Bundle extras = location.getExtras();
       boolean isMockLocation = extras != null && extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false);
    
    }
    

    【讨论】:

    • 有什么理由不能只使用isFromMockProvider() 方法的结果?似乎文档很清楚,如果它是模拟位置,它应该返回 true。
    • @NormanH 我正在处理使用位置管理器的旧代码。对于 Marshmallow,我使用了 location.isFromMockProvider() 。一旦我启动 FakeGPS isFromMockProvider() 就会返回 true。在这里,如果我开始甚至停止,isFromMockProvider() 总是返回 true。看起来 FakeGPS 会覆盖 Location Mnaager 的位置,即使在停止 FakeGPS 之后,位置管理器也不会再次启动。有什么建议这里可能出了什么问题?
    • 似乎 isFromMockProvider 可能会让你误报,根据这篇文章:klaasnotfound.com/2016/05/27/…。我想知道它是否已修复。
    • 根据我的经验,isFromMockProvider() 和 KEY_MOCK_LOCATION extra 总是包含完全相同的信息。此外,如上面评论中所述,两者都可能不时出错(即模拟未标记为此类)。到目前为止,这还没有解决。有关更多信息,请参阅here 和我在下面的答案...要使用 API 15+ 可靠地抑制非 root 设备上的模拟位置,您可以使用我写的 this class
    【解决方案2】:

    接受的答案是一个可行的解决方案,但是,为了完整起见,我想补充一些要点。

    检测模拟位置的最佳内置方法(不仅从 Marshmallow 开始,而且从 API 18+ 开始)是使用Location.isFromMockProvider(),如其他答案和 cmets 所述。

    我在不同设备和操作系统版本上广泛试验了模拟位置,得出以下结论:

    • KEY_MOCK_LOCATION extra 具有与 .isFromMockProvider() 完全相同的信息,即.isFromMockProvider() 将在 extra 存在时返回 true,而在不存在时返回 false。换句话说,它没有提供任何附加值,只是一种更复杂的方式来确定某个位置是否被其提供者标记为模拟。请参阅here 了解更多信息。
      所以我肯定会推荐使用.isFromMockProvider()

    • extra 和 getter 都可能偶尔返回假阴性,即有问题的位置是一个 mock,但没有这样标记。对于某些用例来说,这显然非常糟糕。如果您想了解更多信息,我已就此主题写了详细的blog post

    在与 Android 位置(和模拟标签问题)斗争了很长一段时间后,我发布了 LocationAssistant,这是一个实用程序类,可以可靠地拒绝使用 API 15+ 的无根设备上的模拟位置。它还减轻了您大部分 FusedLocationProvider 样板的负担。也许您会发现它对您的下一个位置感知应用项目很有用。

    【讨论】:

      【解决方案3】:

      This answer 似乎不适合我。 extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false) 总是返回 false。

      但是,我这样做了:

      @Override
      public void onLocationChanged (Location location){
          boolean isMockLocation = location.isFromMockProvider();
      }
      

      我开始得到正确的结果。

      【讨论】:

        【解决方案4】:

        在 marshmallow 中,您可以使用 AppOpsManager 检查 mock_location。

        类似的答案在这里:How to read selected mock location app in Android M - API 23

        【讨论】:

          【解决方案5】:

          这不起作用总是返回 false 也 FusedLocationProviderApi 不推荐使用

          extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false)
          

          以下方法适用于我正确检测模拟位置

          @Override
          public void onLocationChanged (Location location){
              boolean isMockLocation = location.isFromMockProvider();
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-10-10
            • 1970-01-01
            • 2017-07-15
            • 1970-01-01
            • 1970-01-01
            • 2018-05-11
            • 1970-01-01
            相关资源
            最近更新 更多