Android模擬位置資訊
阿新 • • 發佈:2019-01-25
Android手機設定——開發人員選擇中有一個“允許模仿位置”的選項,開發人員對開發的某些定位軟體(一般為地圖軟體)做測試的時候使用的,功能是模擬手機目前所處的位置(比如手機當前實際位置在中國,但測試軟體時要求測試條件為美國,就可以使用該功能進行測試軟體模擬定位)。
直接看程式碼:
package cn.vn.test; import android.annotation.SuppressLint; public class SetMockLocation extends Activity { private static final String TAG = "SetLocation"; private LocationManager mLocationManager; private Context mContext; private String mMockProviderName = LocationManager.GPS_PROVIDER; private double mLongitude = 40.052462; private double mLatitude = 116.29064; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG,"onCreate"); mContext=this; mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); enableTestProvider(); setLocation();//設定模擬位置資訊,也可以建一個thread不斷設定虛擬位置資訊。 } @Override public void onStart() { super.onStart(); } public void enableTestProvider(){ ContentResolver res = mContext.getContentResolver(); //獲取gps的狀態,false為關閉,true為開啟。 boolean gps_enable = Settings.Secure.isLocationProviderEnabled( res, android.location.LocationManager.GPS_PROVIDER); if(gps_enable){ //關閉gps Settings.Secure.setLocationProviderEnabled(res,LocationManager.GPS_PROVIDER, false); } //獲取“允許模擬地點”的狀態,0為不允許,1為允許。 int mock_enable = Settings.Secure.getInt( res, Settings.Secure.ALLOW_MOCK_LOCATION, 0); if(mock_enable == 0){ try { //開啟 允許模擬地點 Settings.Secure.putInt(res, Settings.Secure.ALLOW_MOCK_LOCATION, 1); } catch (Exception e) { Log.e(TAG, "write error", e); } } mLocationManager.addTestProvider(mMockProviderName, "requiresNetwork" == "", "requiresSatellite" == "", "requiresCell" == "", "hasMonetaryCost" == "", "supportsAltitude" == "", "supportsSpeed" == "", "supportsBearing" == "supportsBearing", Criteria.POWER_LOW, Criteria.ACCURACY_FINE); mLocationManager.setTestProviderEnabled(mMockProviderName, true); } @SuppressLint("NewApi") private void setLocation(){ Log.d(TAG,"setLocation"); Location loc = new Location(mMockProviderName);//這裡是模擬的gps位置資訊,當然也可以設定network位置資訊了。 loc.setAccuracy(Criteria.ACCURACY_FINE); loc.setTime(System.currentTimeMillis());//設定當前時間 loc.setLatitude(mLongitude); //設定緯度 loc.setLongitude(mLatitude); //設定經度 loc.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); mLocationManager.setTestProviderLocation(mMockProviderName, loc); } public void unenableTestProvider(){ int mock_enable = Settings.Secure.getInt( mContext.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0); if(mock_enable == 0) return; try { mLocationManager.clearTestProviderEnabled(mMockProviderName); mLocationManager.removeTestProvider(mMockProviderName); } catch (Exception e) { Log.e(TAG, "", e); } try { //關閉 允許模擬地點 Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0); } catch (Exception e) { Log.e(TAG, "write error", e); } } @Override public void onDestroy() { super.onDestroy(); unenableTestProvider(); } }
以上的程式碼中關閉gps和開啟允許模擬位置會報錯:java.lang.SecurityException: Permission denial: writing to secure settings requires android.permission.WRITE_SECURE_SETTINGS。
配置檔案中加入許可權:
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
即使這樣依舊會報上面的錯誤,這是因為只有system app才可以有這個許可權。
這就要把上面的設定gps和模擬位置的程式碼刪掉。自己去設定中開啟模擬位置資訊。
這樣就可以設定想要的位置了。
別的一些軟體可能不顯示這個模擬位置,將獲取位置資訊改為僅裝置。這樣應該就可以了。
這些設定的模擬位置,我們可以通過平常獲取gps和network位置資訊獲取到。