2016-11-13 80 views
1

我看到,在市場上有很多模擬位置應用程序適用於整個系統。 (這意味着當我們使用谷歌地圖,超級...)它會顯示新的位置。如何寫模擬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_PROVIDERNETWORK_PROVIDERPASSIVE_PROVIDER。請告訴我如何做到這一點。

回答

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地圖並且請勿使用高精度,請設置僅設備模式。

+0

我改變了我的代碼。我定期調用'setupMockLocation',但它仍然不起作用。也許還有其他錯誤? –

+0

當你離開你的應用程序時發生了什麼?您應該在服務中運行相關代碼,因爲在切換到Google地圖(或其他任何地方)後,您的活動(和模擬位置)將停止,然後Google地圖會收到新的位置信息。 – Blackkara

+0

當我離開我的應用程序時,線程仍定期運行模擬位置(我已通過打印日誌進行檢查)。 –

相關問題