我试图为使用模拟位置来操纵我的应用的人提供一些保护。我意识到100%无法阻止......我只是想尽我所能。
该应用在其主要活动中使用Google位置服务(部分播放服务)。
onLocationChanged()方法是:
public void onLocationChanged(Location location) {
this.mCurrentLocation = location;
if (Build.VERSION.SDK_INT > 17 && mCurrentLocation.isFromMockProvider()) {
Log.i(TAG, "QQ Location is MOCK");
// TODO: add code to stop app
// otherwise, currently, location will never be updated and app will never start
} else {
Double LAT = mCurrentLocation.getLatitude();
Double LON = mCurrentLocation.getLongitude();
if ((LAT.doubleValue() > 33.309171) || (LAT.doubleValue() < 33.226442) || (LON.doubleValue() < -90.790165) || (LON.doubleValue() > -90.707081)) {
buildAlertMessageOutOfBounds();
} else if (waiting4FirstLocationUpdate) {
Log.i(TAG, "YYY onLocationChanged() determines this is the FIRST update.");
waiting4FirstLocationUpdate = false;
setContentView(R.layout.activity_main);
startDisplayingLists();
}
}
}
位置服务工作完美,一般都适用于应用程序,但是当我使用Android Studio(Nexus One API 23)在模拟器中运行应用程序时,我使用扩展控件(模拟)设置位置,应用程序只是继续正常工作,所以似乎条件:
if (Build.VERSION.SDK_INT > 17 && mCurrentLocation.isFromMockProvider())
返回false。
这对我没有任何意义。有谁知道为什么会这样?
谢谢!
答案 0 :(得分:3)
简短回答:.isFromMockProvider不可靠。某些虚假地点未被正确检测到。 我花了大量时间研究这个问题并撰写了一篇关于它的detailed blog post。
我还花时间找到一个解决方案,可以在所有最近/相关的Android版本中可靠地抑制模拟位置,并创建了一个名为LocationAssistant的实用程序类来完成这项工作。
简而言之(使用前面提到的 LocationAssistant ):
在您的gradle文件中设置清单和Google Play服务的权限。
将文件LocationAssistant.java复制到您的项目中。
在您的Activity的onCreate()
方法中,使用所需参数实例化LocationAssistant
。例如,要大致每5秒接收高精度位置更新并拒绝模拟位置,请致电new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, false)
。最后一个参数指定不允许使用模拟位置。
使用您的活动启动/停止助理,并通知其权限/位置设置更改(有关详细信息,请参阅documentation)。
在onNewLocationAvailable(Location location)
中享受位置更新。如果您选择拒绝模拟位置,则仅使用非模拟位置调用回调。
还有一些方法可以实现,但基本上就是这样。显然,有一些方法可以使用有根设备来解决模拟提供程序检测问题,但是在库存,非根设备上,拒绝应该可靠地工作。