您的位置:首页 > 移动开发 > Android开发

Android模拟位置实现

2015-09-06 15:07 696 查看
http://blog.csdn.net/Aslanchen/article/details/43449765

http://www.cnmo.com/soft/141018.html

Android上有很多位置欺骗软件,当你打开微信搜索附近的,可以通过这类软件把你位置定位到指定位置。

今天,我们就使用Android自带的模拟位置功能来实现。

准备工作:

1:设置-开发者选项-允许模拟位置 打钩

2:我这里使用了百度地图,所以需要去申请一个地图的key。传送门申请key

3:定位方式修改成 仅限GPS

4:不是所有软件的GPS都能被欺骗,比如QQ就不行,可能是QQ的定位方式经过处理吧,具体还需要检验,我只用微信作为测试,测试是成功的。

上代码

1:界面

Demo很简单,就一个界面,界面上一个百度地图,用来选择位置,一个确认按钮Button,一个显示位置文字的TextView

布局文件activity_main.xml如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >

<Button
android:id="@+id/bt_Ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确定" />

<TextView
android:id="@+id/tv_location"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >

<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />
</RelativeLayout>

</LinearLayout>


2:代码

需要的接口:

[java] view plaincopy

LocationListener 模拟GPS接口

BDLocationListener 百度定位接口

OnMapClickListener 地图点击接口

OnMarkerDragListener 地图上拖动接口

OnGetGeoCoderResultListener 反地理信息搜索接口

变量定义:

private String mMockProviderName = LocationManager.GPS_PROVIDER;;
private Button bt_Ok;
private LocationManager locationManager;
private double latitude = 31.3029742, longitude = 120.6097126;// 默认常州
private Thread thread;// 需要一个线程一直刷新
private Boolean RUN = true;
private TextView tv_location;

boolean isFirstLoc = true;// 是否首次定位
// 定位相关
private LocationClient mLocClient;
private LocationMode mCurrentMode;// 定位模式
private BitmapDescriptor mCurrentMarker;// 定位图标
private MapView mMapView;
private BaiduMap mBaiduMap;

// 初始化全局 bitmap 信息,不用时及时 recycle
private BitmapDescriptor bd = BitmapDescriptorFactory.fromResource(R.drawable.icon_gcoding);
private Marker mMarker;
private LatLng curLatlng;
private GeoCoder mSearch;


关键代码:

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

/**
* iniView 界面初始化
*
*/
private void iniView() {
bt_Ok = (Button) findViewById(R.id.bt_Ok);
tv_location = (TextView) findViewById(R.id.tv_location);
// 地图初始化
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
// 开启定位图层
mBaiduMap.setMyLocationEnabled(true);
// 定位初始化
mLocClient = new LocationClient(this);
}

/**
* iniListner 接口初始化
*
*/
private void iniListner() {
bt_Ok.setOnClickListener(this);
mLocClient.registerLocationListener(this);
mBaiduMap.setOnMapClickListener(this);
mBaiduMap.setOnMarkerDragListener(this);

// 初始化搜索模块,注册事件监听
mSearch = GeoCoder.newInstance();
mSearch.setOnGetGeoCodeResultListener(this);
}

/**
* iniData 数据初始化
*
*/
private void iniData() {
inilocation();
iniMap();
}

/**
* iniMap 初始化地图
*
*/
private void iniMap() {
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);// 打开gps
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(1000);
mCurrentMode = LocationMode.NORMAL;
// 缩放
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(14.0f);
mBaiduMap.setMapStatus(msu);

mBaiduMap.setMyLocationConfigeration(new MyLocationConfiguration(mCurrentMode, true,
mCurrentMarker));
mLocClient.setLocOption(option);
mLocClient.start();
initOverlay();

// 开启线程,一直修改GPS坐标
thread = new Thread(new Runnable() {

@Override
public void run() {
while (RUN) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
setLocation(longitude, latitude);
}
}
});
thread.start();
}

/**
* initOverlay 设置覆盖物,这里就是地图上那个点
*
*/
private void initOverlay() {
LatLng ll = new LatLng(latitude, longitude);
OverlayOptions oo = new MarkerOptions().position(ll).icon(bd).zIndex(9).draggable(true);
mMarker = (Marker) (mBaiduMap.addOverlay(oo));
}

/**
* inilocation 初始化 位置模拟
*
*/
private void inilocation() {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.addTestProvider(mMockProviderName, false, true, false, false, true, true,
true, 0, 5);
locationManager.setTestProviderEnabled(mMockProviderName, true);
locationManager.requestLocationUpdates(mMockProviderName, 0, 0, this);
}

/**
* setLocation 设置GPS的位置
*
*/
private void setLocation(double longitude, double latitude) {
Location location = new Location(mMockProviderName);
location.setTime(System.currentTimeMillis());
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setAltitude(2.0f);
location.setAccuracy(3.0f);
locationManager.setTestProviderLocation(mMockProviderName, location);
}

@Override
public void onLocationChanged(Location location) {
double lat = location.getLatitude();
double lng = location.getLongitude();
Log.i("gps", String.format("location: x=%s y=%s", lat, lng));
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub

}

@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub

}

@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}

@Override
protected void onResume() {
mMapView.onResume();
super.onResume();
}

@Override
public void onBackPressed() {
thisFinish();
}

@Override
protected void onDestroy() {
RUN = false;
thread = null;

// 退出时销毁定位
mLocClient.stop();
// 关闭定位图层
mBaiduMap.setMyLocationEnabled(false);
mMapView.onDestroy();
mMapView = null;
bd.recycle();
super.onDestroy();
}

private void thisFinish() {
AlertDialog.Builder build = new AlertDialog.Builder(this);
build.setTitle("提示");
build.setMessage("退出后,将不再提供定位服务,继续退出吗?");
build.setPositiveButton("确认", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
build.setNeutralButton("最小化", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
moveTaskToBack(true);
}
});
build.setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {

}
});
build.show();
}

@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.bt_Ok:
latitude = curLatlng.latitude;
longitude = curLatlng.longitude;
break;
}
}

/**
* 定位SDK监听函数
*/
@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null || mMapView == null) {
return;
}

if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
setCurrentMapLatLng(ll);
}
}

@Override
public void onMapClick(LatLng arg0) {
setCurrentMapLatLng(arg0);
}

@Override
public boolean onMapPoiClick(MapPoi arg0) {
// TODO Auto-generated method stub
return false;
}

/**
* setCurrentMapLatLng 设置当前坐标
*/
private void setCurrentMapLatLng(LatLng arg0) {
curLatlng = arg0;
mMarker.setPosition(arg0);

// 设置地图中心点为这是位置
LatLng ll = new LatLng(arg0.latitude, arg0.longitude);
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(u);

// 根据经纬度坐标 找到实地信息,会在接口onGetReverseGeoCodeResult中呈现结果
mSearch.reverseGeoCode(new ReverseGeoCodeOption().location(arg0));
}

/**
* onMarkerDrag 地图上标记拖动结束
*/
@Override
public void onMarkerDrag(Marker arg0) {
// TODO Auto-generated method stub

}

/**
* onMarkerDragEnd 地图上标记拖动结束
*/
@Override
public void onMarkerDragEnd(Marker marker) {
setCurrentMapLatLng(marker.getPosition());
}

/**
* onMarkerDragStart 地图上标记拖动开始
*/
@Override
public void onMarkerDragStart(Marker arg0) {
// TODO Auto-generated method stub

}

/**
* onGetGeoCodeResult 搜索(根据实地信息-->经纬坐标)
*/
@Override
public void onGetGeoCodeResult(GeoCodeResult arg0) {
// TODO Auto-generated method stub

}

/**
* onGetReverseGeoCodeResult 搜索(根据坐标-->实地信息)
*/
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(this, "抱歉,未能找到结果", Toast.LENGTH_LONG).show();
return;
}

tv_location.setText(String.format("伪造位置:%s", result.getAddress()));
}


到底,就结束了,现在运行我们的程序,然后选择一个地点,然后点击确认

接着,打开微信,打开附近的人,查看结果,如果没有修改定位,多尝试几次打开附近,如果还不行,那就参考 准备工作 是否做好

程序github地址:https://github.com/Aslanchen/SimulateGps
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: