如何检查 Android Marshmallow 中的模拟位置?
How to check for Mock Location in Android Marshmallow?
如何在Android Marshmallow
中检测位置是否被Mock Location
触发?
之前我用的是Settings.Secure.ALLOW_MOCK_LOCATION
但是,在 API 级别 23 中,这已被弃用。
我想检查触发器是假位置还是原始 GPS?
现在,有什么方法可以检查 Mock Location
是否启用 Android Marshmallow
?
如果您正在使用 FusedLocationProviderApi
并在 callback/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);
}
在 marshmallow 中,您可以使用 AppOpsManager 检查 mock_location。
这里有类似的答案:How to read selected mock location app in Android M - API 23
似乎对我不起作用。 extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false)
总是返回 false。
然而,我这样做了:
@Override
public void onLocationChanged (Location location){
boolean isMockLocation = location.isFromMockProvider();
}
我开始得到正确的结果。
接受的答案是一个可行的解决方案,但是,为了完整起见,我想补充一些要点。
检测模拟位置的最佳内置方法(不仅自 Marshmallow 以来,而且自 API 18+ 以来)是使用 Location.isFromMockProvider(),如其他答案和评论。
我在不同设备和 OS 版本上对模拟位置进行了广泛试验,得出以下结论:
KEY_MOCK_LOCATION
extra 包含与 .isFromMockProvider()
完全相同的信息,即 .isFromMockProvider()
将 return true
当 extra 是存在,false
不存在。换句话说,它不提供任何附加值,只是一种更复杂的方法,用于查明某个位置是否被其提供者标记为模拟位置。有关详细信息,请参阅 here。
所以我肯定会推荐使用 .isFromMockProvider()
.
extra 和 getter 偶尔会 return 假阴性 ,即有问题的位置是模拟但不是标记为这样。对于某些用例来说,这显然非常糟糕。如果你想了解更多,我已经写了一篇关于这个主题的详细文章blog post。
在与 Android 位置(和模拟标签问题)斗争了很长一段时间后,我发布了 LocationAssistant,一个实用程序 class,它将可靠地拒绝非模拟位置API 15+ 的 root 设备。它还使您从大多数 FusedLocationProvider 样板文件中解脱出来。也许您会发现它对您的下一个位置感知应用程序项目很有用。
这并不总是有效 return false 并且 FusedLocationProviderApi 已被 弃用
extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false)
下面的方法对我来说很有效,可以正确检测模拟位置
@Override
public void onLocationChanged (Location location){
boolean isMockLocation = location.isFromMockProvider();
}
如何在Android Marshmallow
中检测位置是否被Mock Location
触发?
之前我用的是Settings.Secure.ALLOW_MOCK_LOCATION
但是,在 API 级别 23 中,这已被弃用。
我想检查触发器是假位置还是原始 GPS?
现在,有什么方法可以检查 Mock Location
是否启用 Android Marshmallow
?
如果您正在使用 FusedLocationProviderApi
并在 callback/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);
}
在 marshmallow 中,您可以使用 AppOpsManager 检查 mock_location。
这里有类似的答案:How to read selected mock location app in Android M - API 23
extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false)
总是返回 false。
然而,我这样做了:
@Override
public void onLocationChanged (Location location){
boolean isMockLocation = location.isFromMockProvider();
}
我开始得到正确的结果。
接受的答案是一个可行的解决方案,但是,为了完整起见,我想补充一些要点。
检测模拟位置的最佳内置方法(不仅自 Marshmallow 以来,而且自 API 18+ 以来)是使用 Location.isFromMockProvider(),如其他答案和评论。
我在不同设备和 OS 版本上对模拟位置进行了广泛试验,得出以下结论:
KEY_MOCK_LOCATION
extra 包含与.isFromMockProvider()
完全相同的信息,即.isFromMockProvider()
将 returntrue
当 extra 是存在,false
不存在。换句话说,它不提供任何附加值,只是一种更复杂的方法,用于查明某个位置是否被其提供者标记为模拟位置。有关详细信息,请参阅 here。
所以我肯定会推荐使用.isFromMockProvider()
.extra 和 getter 偶尔会 return 假阴性 ,即有问题的位置是模拟但不是标记为这样。对于某些用例来说,这显然非常糟糕。如果你想了解更多,我已经写了一篇关于这个主题的详细文章blog post。
在与 Android 位置(和模拟标签问题)斗争了很长一段时间后,我发布了 LocationAssistant,一个实用程序 class,它将可靠地拒绝非模拟位置API 15+ 的 root 设备。它还使您从大多数 FusedLocationProvider 样板文件中解脱出来。也许您会发现它对您的下一个位置感知应用程序项目很有用。
这并不总是有效 return false 并且 FusedLocationProviderApi 已被 弃用
extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false)
下面的方法对我来说很有效,可以正确检测模拟位置
@Override
public void onLocationChanged (Location location){
boolean isMockLocation = location.isFromMockProvider();
}