lukassteiner lukassteiner - 4 months ago 25
Java Question

Use mock location without setting it in settings

I am writing an App which makes use of the location mocking possibility in android.

What I would like to achive is to mock my location without setting the "allow mock locations" flag in the developer options.

I know that it is possible, because is works with this app:
https://play.google.com/store/apps/details?id=com.lexa.fakegps&hl=en

What I tried:

Generate an apk, move it to /system/app, do a reboot

And I also tried it with and without the ACCESS_MOCK_LOCATION permission in the manifest.

But it all lead to this exception:

RuntimeException: Unable to start Activity: SecurityException: Requires ACCESS_MOCK_LOCATION secure setting

Answer

I have decompiled com.lexa.fakegps you mentioned in question, and what it do like this:

private int setMockLocationSettings() {
    int value = 1;
    try {
        value = Settings.Secure.getInt(getContentResolver(),
                Settings.Secure.ALLOW_MOCK_LOCATION);
        Settings.Secure.putInt(getContentResolver(),
                Settings.Secure.ALLOW_MOCK_LOCATION, 1);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return value;
}

private void restoreMockLocationSettings(int restore_value) {
    try {
        Settings.Secure.putInt(getContentResolver(),
                Settings.Secure.ALLOW_MOCK_LOCATION, restore_value);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/* every time you mock location, you should use these code */
int value = setMockLocationSettings();//toggle ALLOW_MOCK_LOCATION on
try {
    mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, fake_location);
} catch (SecurityException e) {
    e.printStackTrace();
} finally {
    restoreMockLocationSettings(value);//toggle ALLOW_MOCK_LOCATION off
}

Because the execution time of these code is very short, other apps can hardly detect the change of ALLOW_MOCK_LOCATION.

Also you need,
1. require root access to your device
2. move your app to /system/app or /system/priv-app

I tried it in my project and it works fine.