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(); } }
配置文件中加入权限:
<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位置信息获取到。