检测模拟位置不起作用(Android) [英] Detecting Mock Location Not Working (Android)
问题描述
我正在尝试设置一些保护措施,以防止人们使用模拟位置来操纵我的应用.我意识到不可能100%阻止...我只是在尽我所能.
I'm trying to set some protection against people using mock locations to manipulate my app. I realise that it's impossible to prevent 100%... I'm just trying to do what I can.
该应用在其主要活动中使用Google定位服务(游戏服务的一部分).
The app uses Google location services (part of play services) in its main activity.
onLocationChanged()方法为:
The onLocationChanged() method is:
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)的模拟器中运行该应用程序,并使用扩展控件(模拟)设置位置时,应用程序仍然可以正常运行,因此看起来情况如下:
The location services work perfectly and all is well with the app in general, but when I run the app in an emulator with Android Studio (Nexus One API 23), and I set the location using extended controls (mock), the app just continues to work as normal, and so it seems that the condition:
if (Build.VERSION.SDK_INT > 17 && mCurrentLocation.isFromMockProvider())
返回假.
这对我来说没有任何意义.有谁知道为什么会这样?
This doesn't make any sense to me. Does anyone know why this would happen?
谢谢!
推荐答案
The short answer: .isFromMockProvider is unreliable. Some fake locations are not properly detected as such. I have spent an extensive amount of time researching this and written a detailed blog post about it.
我还花了一些时间来找到一种解决方案,以在所有最新/相关的Android版本中可靠地抑制模拟位置,并制作了一个实用程序类,称为 LocationAssistant ,即可完成工作.
I also spent time to find a solution to reliably suppress mock locations across all recent/relevant Android versions and made a utility class, called the LocationAssistant, that does the job.
简而言之(使用上述 LocationAssistant ):
In a nutshell (using the aforementioned LocationAssistant):
-
在清单中设置权限,并在gradle文件中设置Google Play服务.
Set up permissions in your manifest and Google Play Services in your gradle file.
复制文件 LocationAssistant.java 到您的项目.
在活动"的onCreate()
方法中,使用所需参数实例化LocationAssistant
.例如,要大致每5秒接收一次高精度位置更新并拒绝模拟位置,请致电new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, false)
.最后一个参数指定不应允许模拟位置.
In the onCreate()
method of your Activity, instantiate a LocationAssistant
with the desired parameters. For example, to receive high-accuracy location updates roughly every 5 seconds and reject mock locations, call new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, false)
. The last argument specifies that mock locations shouldn't be allowed.
使用活动"启动/停止助手,并通知其权限/位置设置更改(请参见文档以获取详细信息).
Start/stop the assistant with your Activity and notify it of permission/location settings changes (see the documentation for details).
享受onNewLocationAvailable(Location location)
中的位置更新.如果您选择拒绝模拟位置,则仅在非模拟位置调用该回调.
Enjoy location updates in onNewLocationAvailable(Location location)
. If you chose to reject mock locations, the callback is only invoked with non-mock locations.
还有更多方法可以实现,但实际上就是这样.显然,有一些方法可以绕过使用root的设备进行模拟提供程序检测,但是对于非rooted的库存设备,拒绝应该可靠地工作.
There are some more methods to implement, but essentially this is it. Obviously, there are some ways to get around mock provider detection with rooted devices, but on stock, non-rooted devices the rejection should work reliably.
这篇关于检测模拟位置不起作用(Android)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!