如何编写mock gps提供程序会影响整个系统应用程序

时间:2016-11-13 13:02:18

标签: android gps

我看到市场上有很多模拟位置应用适用于整个系统。 (这意味着当我们使用谷歌地图时,超级......)它将显示新的位置。

我已经学过一些教程。这是我的示例代码:

public class MainActivity extends AppCompatActivity {

    LocationManager mLocationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLocationManager  = (LocationManager) getSystemService(LOCATION_SERVICE);

        setupMockLocations(LocationManager.GPS_PROVIDER);
        setupMockLocations(LocationManager.NETWORK_PROVIDER);
        setupMockLocations(LocationManager.PASSIVE_PROVIDER);

    }

       private void setupMockLocations(final String providerName) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            for (; ; ) {
                mLocationManager.addTestProvider(providerName, false, //requiresNetwork,
                        false, // requiresSatellite,
                        false, // requiresCell,
                        false, // hasMonetaryCost,
                        false, // supportsAltitude,
                        false, // supportsSpeed, s
                        false, // upportsBearing,
                        Criteria.POWER_LOW, // powerRequirement
                        Criteria.ACCURACY_FINE); // accuracy

                mLocationManager.setTestProviderEnabled(providerName, true);
                location.setTime(System.currentTimeMillis());
                location.setAccuracy(1);
                location.setTime(System.currentTimeMillis());

                Method locationJellyBeanFixMethod = null;
                try {
                    locationJellyBeanFixMethod = Location.class.getMethod("makeComplete");
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }

                if (locationJellyBeanFixMethod != null) {
                    try {
                        locationJellyBeanFixMethod.invoke(location);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }

                mLocationManager.setTestProviderLocation(providerName, location);


                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                Log.e("print", "mocking " + providerName);
            }

        }
    }).run();
}


}

但看起来这段代码不起作用。 (它应该在Google地图上显示我的sampleLocation而不是当前位置)。我也伪造了GPS_PROVIDER NETWORK_PROVIDERPASSIVE_PROVIDER。请告诉我怎么做。

1 个答案:

答案 0 :(得分:1)

如何编写模拟gps提供程序会影响整个系统应用程序

它已经影响了整个系统,它确实有效。但条件可能会改变结果。例如,在你的情况下,

当您致电setupMockLocations(LocationManager.GPS_PROVIDER); GPS提供商缓存您的假位置时。但是在此时(或之后),如果任何其他应用程序发出GPS位置请求并接收新的GPS位置,那么您的虚假位置将被覆盖。

您的代码是正确的,但只需定期致电setupMockLocations(...);以防止出现上述情况。

此示例适用于我,请考虑步骤

public class SampleMocker {

    private int mPeriod = 2 * 1000;
    private Location mMockLocation;
    private LocationManager mLocationManager;
    private Handler mHandler = new Handler();

    public SampleMocker(Context context){
        mLocationManager = (LocationManager)
            context.getSystemService(Context.LOCATION_SERVICE);

        mMockLocation = new Location(LocationManager.GPS_PROVIDER);
        mLocationManager.addTestProvider(GPS_PROVIDER, false, false, false, 
        false, false, true, true, 0, 5);
        mLocationManager.setTestProviderEnabled(GPS_PROVIDER, true);
    }

    private void start(){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mMockLocation.setTime(System.currentTimeMillis());

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                    mMockLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
                }

                mLocationManager.setTestProviderLocation(GPS_PROVIDER, mMockLocation);

                mHandler.postDelayed(this, mPeriod);
            }
        });
    }
}

此代码定期在每2秒设置模拟位置。 private int mPeriod = 2 * 1000;

您应该调整使用时间。因为如果其他应用程序可以用较低的期限进行位置请求。那么你的模拟位置不会经常出现。

要进行测试:运行此代码时,请打开Goog​​le地图并不要使用高精度,请设置仅设备模式。