Android系统中提供了模拟GPS坐标的功能,可以很方便的帮助我们测试不同地理位置下应用中各个功能效果。

模拟器中模拟位置方法

模拟器与真机中的模拟手段有所差异,在模拟器中,可以通过Android的调试工具,或是命令行来修改GPS坐标点。

首先通过adb命令的修改方法:

adb geo fix 116.813752 39.820015

注意如果链接了多个设备,adb命令需要添加-s参数指定模拟器设备。

同样原理,可以使用Android SDK中的DDMS工具来修改GPS坐标;打开DDMS,可以看到Emulator面板中的GPS设置选项,

当打开模拟器运行时,这里就会变成可操作状态。

对于第三方模拟器,Genymotion也提供了这样的功能。不仅可以通过GenyMotion虚拟机的控制面板调节GPS参数(截图略),还可以通过Genymotion提供的Java API修改坐标点:

Context mContext = getActivity();

GenymotionManager genymotion = GenymotionManager.getGenymotionManager(mContext);

genymotion.getGps()

.setLatitude(39.820015)

.setLongitude(116.813752);

真机中模拟位置方法

真机中模拟GPS位置的方法稍复杂一点。

首先,需要到系统设置中“开发者选项”处,将其中的“允许模拟位置”打开。

然后我们需要编写一个简单的APP,来通过系统API修改GPS坐标值。

这涉及了一个权限:

在Eclipse环境下,直接修改AndroidManifest即可;

在Android Studio环境下,需要建立src/debug这个文件夹,然后在里面创建一个debug版本的AndroidManifest.xml文件,才能添加这个权限。

然后来编写代码:

在LocationManager中,提供了一个接口

public void addTestProvider(String name,

boolean requiresNetwork,

boolean requiresSatellite,

boolean hasMonetaryCost,

boolean supportsAltitude,

boolean supportsBearing,

int accuracy)

参数比较多,但接口的用途还是很清晰的——添加一个用于模拟位置的Provider。然后我们可以向这个Provider中设定模拟的位置:

private LocationManager mLocManager;

mLocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

mLocManager.addTestProvider(LocationManager.GPS_PROVIDER,

"requiresNetwork" == "",

"requiresSatellite" == "",

"requiresCell" == "",

"hasMonetaryCost" == "",

"supportsAltitude == "", "supportsSpeed" == "", "supportsBearing" == "", Criteria.NO_REQUIREMENT, Criteria.ACCURACY_COARSE); // 创建新的Location对象,并设定必要的属性值 Location newLocation = new Location(LocationManager.GPS_PROVIDER); newLocation.setLatitude(39.820015); newLocation.setLongitude(116.813752); newLocation.setAccuracy(500); newLocation.setTime(System.currentTimeMillis()); newLocation.setElapsedRealtimeNanos(System.currentTimeMillis()); // 开启测试Provider mLocManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true); mLocManager.setTestProviderStatus(LocationManager.GPS_PROVIDER, LocationProvider.AVAILABLE, null, System.currentTimeMillis()); // 设置最新位置 mLocManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, newLocation);

不过这种方式设置坐标后,并没有触发GPS的onLocationChanged回调函数,目前还不清楚后面的原理。但可以使用getLastKnownLocation接口获取:

Location tmp = mLocManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

Log.i(TAG, tmp.getLatitude() + ", " + tmp.getLongitude());

真机模拟位置原理

在真机模拟位置点的过程中,我们调用了很多TestProvider有关的API。

首先来看一下addTestProvider函数,其最终调用到的逻辑位于com.android.server.LocationManagerService中

@Override

public void addTestProvider(String name, ProviderProperties properties, String opPackageName) {

if (!canCallerAccessMockLocation(opPackageName)) {

return;

}

// 由此可以看到无法传入PASSIVE_PROVIDER作为测试使用

if (LocationManager.PASSIVE_PROVIDER.equals(name)) {

throw new IllegalArgumentException("Cannot mock the passive location provider");

}

long identity = Binder.clearCallingIdentity();

synchronized (mLock) {

// remove the real provider if we are replacing GPS or network provider

// 在这里比较传入的Provider名称,如果和GPS_PROVIDER相同,就将真正的GPS_PROVIDER移除掉

if (LocationManager.GPS_PROVIDER.equals(name)

|| LocationManager.NETWORK_PROVIDER.equals(name)

|| LocationManager.FUSED_PROVIDER.equals(name)) {

LocationProviderInterface p = mProvidersByName.get(name);

if (p != null) {

removeProviderLocked(p);

}

}

// 会向mMockProviders中添加这一测试用的provider,以便后续使用

addTestProviderLocked(name, properties);

updateProvidersLocked();

}

Binder.restoreCallingIdentity(identity);

}

因此在我们传入GPS_PROVIDER后,后续请求GPS更新,就会使用我们给定的位置了。

再来看向测试用的PROVIDER设定位置点坐标,其真正逻辑同样位于com.android.server.LocationManagerService中:

@Override

public void setTestProviderLocation(String provider, Location loc, String opPackageName) {

if (!canCallerAccessMockLocation(opPackageName)) {

return;

}

synchronized (mLock) {

MockProvider mockProvider = mMockProviders.get(provider);

if (mockProvider == null) {

throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");

}

// clear calling identity so INSTALL_LOCATION_PROVIDER permission is not required

long identity = Binder.clearCallingIdentity();

// 向mockProvider传入位置点

mockProvider.setLocation(loc);

Binder.restoreCallingIdentity(identity);

}

}

其中mockProvider是从mMockProviders中得到的,在addTestProvider时,addTestProviderLocked函数会向其添加我们设定的provider。

继续追踪到setLocation函数,位于com.android.server.location.MockProvider中:

public void setLocation(Location l) {

mLocation.set(l);

mHasLocation = true;

if (mEnabled) {

try {

// 调用LocationManagerService中的函数,而非应用层可获取到的LocationManager

mLocationManager.reportLocation(mLocation, false);

} catch (RemoteException e) {

Log.e(TAG, "RemoteException calling reportLocation");

}

}

}

还是要回到LocationManagerService中:

@Override

public void reportLocation(Location location, boolean passive) {

checkCallerIsProvider();

if (!location.isComplete()) {

Log.w(TAG, "Dropping incomplete location: " + location);

return;

}

mLocationHandler.removeMessages(MSG_LOCATION_CHANGED, location);

// 向Handler发送MSG_LOCATION_CHANGED消息

Message m = Message.obtain(mLocationHandler, MSG_LOCATION_CHANGED, location);

m.arg1 = (passive ? 1 : 0);

mLocationHandler.sendMessageAtFrontOfQueue(m);

}

最终是在这里发送了MSG_LOCATION_CHANGED消息,但为何没有触发onLocationChanged?还需要研究一下……

android 模拟gps坐标,Android系统中模拟GPS位置相关推荐

  1. GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)

    GPS坐标互转:WGS-84(GPS).GCJ-02(Google地图).BD-09(百度地图) WGS-84:是国际标准,GPS坐标(Google Earth使用.或者GPS模块) GCJ-02:中 ...

  2. 北斗/GPS卫星时钟系统(北斗/GPS卫星授时系统-北斗/GPS卫星校时系统)

    北斗/GPS卫星时钟系统(北斗/GPS卫星授时系统-北斗/GPS卫星校时系统) 北斗/GPS卫星时钟系统(北斗/GPS卫星授时系统-北斗/GPS卫星校时系统) 技术交流-岳峰-15901092122: ...

  3. Win10系统中临时文件夹位置及临时文件的删除

    Win10系统中临时文件夹位置及临时文件的删除 工具/原料 硬件:电脑 操作系统:Windows10 百度经验:jingyan.baidu.com 方法/步骤 1 ①Windows临时文件夹 查找Wi ...

  4. Android系统中模拟GPS位置,Android系统中模拟GPS位置

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? Android系统中提供了模拟GPS坐标的功能,可以很方便的帮助我们测试不同地理位置下应用中各个功能效果. 模拟器中模拟 ...

  5. 安卓编译android.mk,详解安卓系统中的Android.mk文件

    概述    Android.mk文件用来向编译系统描述如何编译你的源代码.更确切地说,该文件其实就是一个小型的Makefile.由于该文件会被NDK的编译工具解析多次,因此应该尽量减少源码中声明变量, ...

  6. android input鼠标坐标,android - 如何在EditText中设置光标位置?

    android - 如何在EditText中设置光标位置? 有两个EditText,在加载页面时,第一个EditText中设置了一个文本,所以现在光标将在EditText的起始位置,我想在第二个Edi ...

  7. android 获取当前坐标,Android获取位置信息的方法

    本文实例为大家分享了Android获取位置信息的具体代码,供大家参考,具体内容如下 1.位置服务的简介:位置服务,英文翻译为Location-Based Services,缩写为LBS,又称为定位服务 ...

  8. GPS问题调试—MobileLog中有关GPS关键LOG的释义

     [DESCRIPTION] 在mobile log中,有很多GPS相关的log出现在main log和kernel log.properties文件中,他们的意思是什么,通过这篇文档进行总结,以便在 ...

  9. c语言实现gps坐标转化,C语言计算GPS卫星位置

    <C语言计算GPS卫星位置>由会员分享,可在线阅读,更多相关<C语言计算GPS卫星位置(8页珍藏版)>请在人人文库网上搜索. 1.C 语 言 计 算GPS卫星位置1 概述在用G ...

  10. matlab如何看机器人末端坐标,关于RobotStudio中机器人末端位置的MATLAB仿真验证

    关于RobotStudio中机器人末端位置的MATLAB仿真验证 最近事情贼多,感觉有点乏力. 主要是最近在着手写一篇关于机器人轨迹规划的文章.随之而来的,当然是一堆的仿真,以及实验平台的搭建,还要想 ...

最新文章

  1. 阿里云发布Quick BIV3.0,人人都能轻松进行在线数据分析
  2. Audition 2020安装教程
  3. BlackArch Linux安装VMware Tools教程
  4. 现代制造工程——考试复习01
  5. 拒绝双写:巧用Lindorm数据订阅
  6. 分享3个数据分析实战项目(附最新资料包)
  7. java完全数判断_java基础之完数判断
  8. Android 音频开发(四) 如何播放一帧音频数据下
  9. SpringMVC XXX-servlet.xml ApplicationContext.xml
  10. PS通道抠图及选区白边处理
  11. 计算机突然蓝屏重启,最近电脑经常蓝屏重启。
  12. Java开发面试常见问题总结
  13. 戴尔服务器安装系统出现蓝屏重启,服务器安装系统蓝屏原因_dell服务器安装系统设计.docx...
  14. Java web学习——Spring MVC项目实例,三层架构通过JDBC链接SQLServer2012
  15. Android开发学习之探究服务
  16. 【236】◀▶IEW-Unit01
  17. mysql按条件查询left_mysql-查询条件下的LEFT JOIN
  18. 【读点论文】CMT: Convolutional Neural Networks Meet Vision Transformers
  19. 数据质量保障的四种原则
  20. 【场景化解决方案】“云上管车”连接道闸系统,企业用车流程更高效

热门文章

  1. BP 神经网络用于模式分类
  2. 数字图像处理理论课件(清华大学计算机科学与技术系)
  3. Chrome扩展程序开发文档(中文译文)
  4. WangEdit富文本编辑器图标修改
  5. python新手入门.pdf_所有Python入门书籍的整理,初学者必看,附赠所有电子版(一)...
  6. VUE集成Office插件NTKO
  7. 17张程序员搞笑图片
  8. 《信号与系统学习笔记》—通信系统(一)
  9. GitHub 10分钟教程
  10. DAY38:域的组成与内网信息搜集