1

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

Community
  • 1
  • 1
owlves
  • 11
  • 2

0 Answers0