寻找在Android上防止/检测GPS欺骗的最佳方法。关于如何实现此目标的任何建议,以及可以采取哪些措施来阻止它?我猜用户必须打开模拟位置来欺骗GPS,如果这样做,那么他们可以欺骗GPS吗?

我想我只需要检测是否启用了模拟位置?还有其他建议吗?

最佳答案

我进行了一些调查并在这里分享我的结果,这可能对其他人有用。
首先,我们可以检查MockSetting选项是否已打开

public static boolean isMockSettingsON(Context context) {
    // returns true if mock location enabled, false if not enabled.
    if (Settings.Secure.getString(context.getContentResolver(),
                                Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"))
        return false;
    else
        return true;
}
其次,我们可以检查设备中是否还有其他应用程序正在使用android.permission.ACCESS_MOCK_LOCATION(位置欺骗应用程序)
public static boolean areThereMockPermissionApps(Context context) {
    int count = 0;

    PackageManager pm = context.getPackageManager();
    List<ApplicationInfo> packages =
        pm.getInstalledApplications(PackageManager.GET_META_DATA);

    for (ApplicationInfo applicationInfo : packages) {
        try {
            PackageInfo packageInfo = pm.getPackageInfo(applicationInfo.packageName,
                                                        PackageManager.GET_PERMISSIONS);

            // Get Permissions
            String[] requestedPermissions = packageInfo.requestedPermissions;

            if (requestedPermissions != null) {
                for (int i = 0; i < requestedPermissions.length; i++) {
                    if (requestedPermissions[i]
                        .equals("android.permission.ACCESS_MOCK_LOCATION")
                        && !applicationInfo.packageName.equals(context.getPackageName())) {
                        count++;
                    }
                }
            }
        } catch (NameNotFoundException e) {
            Log.e("Got exception " , e.getMessage());
        }
    }

    if (count > 0)
        return true;
    return false;
}
如果上述第一种和第二种方法都正确,那么很可能会欺骗或伪造该位置。
现在,可以通过使用位置管理器的API避免欺骗。
我们可以先删除测试提供商,然后再向提供商(网络和GPS)请求位置更新
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);

try {
    Log.d(TAG ,"Removing Test providers")
    lm.removeTestProvider(LocationManager.GPS_PROVIDER);
} catch (IllegalArgumentException error) {
    Log.d(TAG,"Got exception in removing test  provider");
}

lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locationListener);
我已经看到removeTestProvider(〜)在Jelly Bean及更高版本上非常有效。在 Ice Cream Sandwich 之前,此API似乎并不可靠。
Flutter更新:
使用Geolocator并检查Position对象的isMocked属性。

10-07 16:23