After a lot of digging in the end I switched to native Android's API for setting Lat/Long through Mock Locations
NMEA works on layer below system calls and it's generally invisible to the applications
To summarize, this is an approximate flow of GPS data in Android:
GPS Device => GPS driver = (NMEA coordinates) => Android GPS engine = (Lat/Long coordinates) => Android service layer <=> Various API calls from applications
Thus in order to mock locations it wasn't needed to go that deep. 99% of apps rely on Service layer's data and so you can easily obfuscate System's GPS_PROVIDER:
import android.content.Context;
import android.location.*;
import android.os.SystemClock;
import android.util.Log;
/**
* Created by the.Legend on 17/07/2016.
*/
public class FakeGPS {
private LocationManager locationManager;
public static final String GPS_MOCK_PROVIDER = "gps";
public FakeGPS(){
locationManager = (LocationManager) Environment.mainContext.getSystemService(Context.LOCATION_SERVICE);
if(!locationManager.isProviderEnabled(GPS_MOCK_PROVIDER)) {
locationManager.addTestProvider(GPS_MOCK_PROVIDER, false, false,
false, false, true, false, false, 0, 5);
locationManager.setTestProviderEnabled(GPS_MOCK_PROVIDER, true);
locationManager.setTestProviderStatus(GPS_MOCK_PROVIDER, LocationProvider.AVAILABLE, null, System.currentTimeMillis());
}
}
public void applyCoordinates( Double longitude, Double latitude){
if(locationManager.isProviderEnabled(GPS_MOCK_PROVIDER)) {
Double altitude= 0.0;
Float accuracy=3.0f;
long timestamp=System.currentTimeMillis();
try {
Location location = new Location(LocationManager.GPS_PROVIDER);
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setAltitude(altitude);
location.setAccuracy(accuracy);
location.setTime(timestamp);
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); locationManager.setTestProviderLocation(GPS_MOCK_PROVIDER, location);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}