Disable / Check for Mock Location (prevent gps spoofing)

Viewed 177070

Looking to find the best way to prevent / detect GPS spoofing on Android. Any suggestions on how this is accomplished, and what can be done to stop it? I am guessing the user has to turn on mock locations to spoof GPS, if this is done, then they can spoof GPS?

I guess I would need to just detect if Mock Locations are enabled? Any other suggestions?

10 Answers

Paste this in your activity/where you want to validate fake/mock gps

  try {
        if (areThereMockPermissionApps(mContext)) {
            Log.e(TAG, " - " + "Yup its use fake gps");
            List<String> mFakeList = new ArrayList<>();
            mFakeList = getListOfFakeLocationAppsInstalled(mContext); // this will return the fake app list
            for (int a = 0; a < mFakeList.size(); a++) { 
                Log.e(TAG, mFakeList.size() + "  - " + "NameList ----- " + mFakeList.get(a));
            }
        } else
            Log.e(TAG, " - " + "Nope its not use fake gps");
  } catch (Exception w) {
        w.printStackTrace();
  }

Here you can get the list of installed fake/mock app in your device.

    private List<String> getListOfFakeLocationAppsInstalled(Context context) {
    List<String> fakeApps = new ArrayList<>();
    try {
        List<String> runningApps = new ArrayList<>();
        final PackageManager pm = getPackageManager();
        List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);

        for (ApplicationInfo packageInfo : packages) {
            runningApps.add(packageInfo.packageName);
        } // the getLaunchIntentForPackage returns an intent that you can use with startActivity()

        for (String app : runningApps) {
            if (!isSystemPackage(context, app) && hasAppPermission(context, app, "android.permission.ACCESS_MOCK_LOCATION")) {
                fakeApps.add(getApplicationName(context, app));
            }
        }
    } catch (Exception w) {
        w.printStackTrace();
    }
    return fakeApps;
}

Paste this method in your Helper/same class

   public static boolean areThereMockPermissionApps(Context context) {
    int count = 0;
    try {
        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 (PackageManager.NameNotFoundException e) {
                Log.e("MockDeductionAgilanbu", "Got exception --- " + e.getMessage());
            }
        }
    } catch (Exception w) {
        w.printStackTrace();
    }
    if (count > 0)
        return true;
    return false;
}

Below approach is working for me getting proper detection of mock location

@Override
public void onLocationChanged (Location location){
    boolean isMockLocation = location.isFromMockProvider();
}
Related