Im making an apps that mock location and executing set ALLOW_MOCK_LOCATION turned on and off on runtime, so i hopes the other apps which detecting the ALLOW_MOCK_LOCATION flag will never get the ALLOW_MOCK_LOCATION as 1(true).
I read from here that it was possible and said to be fast enough, so other apps can hardly detect the change of ALLOW_MOCK_LOCATION. But what i am get is the other apps still sometimes reed ALLOW_MOCK_LOCATION as 1(true).
Please note that my devices already rooted and i can confirm it does mocked the location well. I also tried move it into /system/app, but still also encounter this problem.
This is the periodical loop which dispatch a asyntask with timeout(I even set the timeout 3 millis !!).
while(RUNNING){
fakeLocation.setAltitude(65.0);
fakeLocation.setAccuracy(Criteria.ACCURACY_FINE);
fakeLocation.setSpeed(0.0f);
fakeLocation.setTime(System.currentTimeMillis());
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
fakeLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
if(locationJellyBeanFixMethod!=null){
try {
locationJellyBeanFixMethod.invoke(fakeLocation);
}catch(Exception ex){}
}
}
new Thread(new Runnable() {
@Override
public void run() {
try {
new MockTask().execute().get(3, TimeUnit.MILLISECONDS);
}catch(TimeoutException e){
changeMockLocationSettings(0);
//Log.d(GLOBAL_VAR.TAG_DEBUG,"Mock location timeout:");
}catch(Exception e){}
}
}).start();
try {Thread.sleep(1500);} catch (InterruptedException e) {}
}
Below is the Asyntask
private class MockTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... param) {
try {
changeMockLocationSettings(1);
locationManager.setTestProviderLocation(GLOBAL_VAR.PROVIDER_NAME, fakeLocation);
changeMockLocationSettings(0);
//Log.d(GLOBAL_VAR.TAG_DEBUG,"location mocked -> "+fakeLocation);
} catch (Exception ex) {
//Log.d(GLOBAL_VAR.TAG_DEBUG,"Failed to mock location:"+ex.toString());
}
return null;
}
@Override
protected void onPostExecute(Void loc) {}
}
And lastly, the method to change ALLOW_MOCK_LOCATION
private boolean changeMockLocationSettings(int value) {
try {
return Settings.Secure.putInt(getApplicationContext().getContentResolver(),Settings.Secure.ALLOW_MOCK_LOCATION, value);
} catch (Exception e) {
Log.d(GLOBAL_VAR.TAG_DEBUG,"Setting allow mock location to "+value+" failed :"+e.toString());
e.printStackTrace();
return false;
}
}
Please help and correct me, and even suggest a better solution if any, and thanks in Advance