如何检查Android Marshmallow中的模拟位置?

Bha*_*ath 9 android location geofencing android-6.0-marshmallow

如何检测Mock LocationAndroid中是否触发了位置Marshmallow

以前,我用过 Settings.Secure.ALLOW_MOCK_LOCATION

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

我想检查触发器是否位于假位置或原始GPS?

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

Nik*_*ski 12

如果您正在使用FusedLocationProviderApisetMockLocation(mGoogleApiClient, fakeLocation);在回调/ pendingIntentCallback中设置了模拟位置,则返回的Location对象包含KEY_MOCK_LOCATIONextra,一个布尔值,表示接收的对象是mock.

@Override

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

}
Run Code Online (Sandbox Code Playgroud)

  • 有什么理由不能只使用[isFromMockProvider()](http://developer.android.com/reference/android/location/Location.html#isFromMockProvider())方法的结果?似乎文档很清楚,如果它是一个模拟位置它应该返回true. (4认同)
  • 根据我的经验,isFromMockProvider()和KEY_MOCK_LOCATION extra总是包含完全相同的信息.此外,如上面的评论中所述,两者都可能是错误的(即模拟不是这样标记的).到目前为止,这还没有解决.请参阅[此处](http://www.klaasnotfound.com/2016/05/27/location-on-android-stop-mocking-me/#comment-2999223312)以及我的回答以获取更多信息...要可靠使用API​​ 15+抑制非根设备上的模拟位置你可以使用[this class](https://github.com/klaasnotfound/LocationAssistant)我写的. (2认同)

Kla*_*und 8

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

检测模拟位置的最佳内置方法(不仅仅是自Marshmallow以来,但自API 18+以来)是使用Location.isFromMockProvider(),如其他答案和评论中所述.

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

  • KEY_MOCK_LOCATION额外熊完全相同的信息.isFromMockProvider(),即.isFromMockProvider()会返回true时,额外的存在,并且false当它不是.换句话说,它没有提供附加价值,只是一种更复杂的方法,可以找出某个位置是否被其提供商标记为模拟.有关详细信息,请参见此处
    所以我肯定会推荐使用.isFromMockProvider().

  • 额外和吸气者都可能偶尔返回假阴性,即所讨论的位置是模拟但未标记为假.对于某些用例来说,这显然非常糟糕.如果您想了解更多信息,我已就此主题撰写了详细的博客文章.

在与Android位置(以及模拟标签问题)挣扎了一段时间之后,我发布了LocationAssistant,这是一个实用程序类,可以在API 15+的非根设备上可靠地拒绝模拟位置.它还使您免受大多数FusedLocationProvider样板的负担.也许您会发现它对您的下一个位置感知应用项目很有用.


set*_*ite 6

这个答案对我来说似乎没有用.extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false)总是返回假.

但是,我这样做了:

@Override
public void onLocationChanged (Location location){
    boolean isMockLocation = location.isFromMockProvider();
}
Run Code Online (Sandbox Code Playgroud)

我开始得到正确的结果.