获取安卓设备的GNSS测量数据方法

2016 年 5 月,Google 在 I/O 开发者会议上宣布,将为 Android Nougat 操作系统中的应用程序提供原始 GNSS 观测数据。
API参考(Google中文官网)DEMO参考(GNSSLogger)

1. 用到的类

注释
LocationManager 用于注册GNSSmeasurement
GnssMeasurementsEvent.Callback 用于从GNSS引擎接收GNSS卫星测量值
GnssMeasurementsEvent 一个包含测量值数据的容器
GnssClock 包含GPS时钟时间戳记的类
Gnssmeasurement 代表GNSS卫星测量的类,其中包含原始信息和计算信息

2.设置权限
必须先在Manifest文件中设置相应的权限,否则将无法获取测量的回调数据

<!--    所需权限--><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/><uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/><uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/><uses-permission android:name="com.google.android.providers.gsf.permission.WRITE_GSERVICES"/><!--    所需权限-->

3.注册GNSSmeasurement

private LocationManager mLocationManager;
private GnssMeasurementsEvent.Callback gnssMeasurementEventListener =new GnssMeasurementsEvent.Callback()
//这里先声明,重写方法将在下一步添加public void RegisterMeasurements(){@SuppressLint("MissingPermission")boolean is_register_success=mLocationManager.registerGnssMeasurementsCallback(gnssMeasurementEventListener);//注册GNSSmeasurement回调监听,返回是否注册成功的信息//测量信息将在GnssMeasurementsEvent.Callback中接收}
//顺便把注销的方法也写了
public void unRegisterMeasurements(){mLocationManager.unregisterGnssMeasurementsCallback(gnssMeasurementEventListener);}

4.重写GnssMeasurementsEvent.Callback里的两个方法

private GnssMeasurementsEvent.Callback gnssMeasurementEventListener =new GnssMeasurementsEvent.Callback() {@Overridepublic void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) {super.onGnssMeasurementsReceived(eventArgs);//这里我们获取到了回调的测量数据容器:GnssMeasurementsEvent eventArgs//TODO:}@Overridepublic void onStatusChanged(int status) {super.onStatusChanged(status);}};

5.将测量数据转换为字符串

  1. 把GnssMeasurementsEvent拆分为GnssClock和Gnssmeasurement
//写一个接收测量信息的方法
public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) {StringBuilder builder=new StringBuilder("GNSS测量数据:\n\n");//这里的toStringClock和toStringMeasurement将写在下一步里builder.append(toStringClock(event.getClock()));//写入gnss时钟的数据builder.append("\n");for (GnssMeasurement measurement : event.getMeasurements()) {builder.append(toStringMeasurement(measurement));//写入gnss测量数据builder.append("\n");}//这里可以写runOnUiThread(...),将builder打印在屏幕上//也可以修改返回值}
  1. 分别把GnssClock和Gnssmeasurement转化为字符串
private String toStringClock(GnssClock gnssClock){//将GPS接收器时钟的值转换为字符串final String format = "   %-4s = %s\n";//定义数据显示格式,“%-4”表示左对齐、不足四位补足四位StringBuilder builder=new StringBuilder("GNSS时钟:\n");DecimalFormat numberFormat = new DecimalFormat("#0.000");//定义格式化数字if (gnssClock.hasLeapSecond()) {//如果闰秒存在则显示闰秒builder.append(String.format(format, "闰秒(LeapSecond)", gnssClock.getLeapSecond()));}builder.append(String.format(format, "硬件时钟(TimeNanos)", gnssClock.getTimeNanos()));//获取以毫秒为单位的GNSS接收器内部硬件时钟值if (gnssClock.hasTimeUncertaintyNanos()) {//获取硬件时钟的误差估计(不确定度)builder.append(String.format(format, "时钟误差估计(TimeUncertaintyNanos)", gnssClock.getTimeUncertaintyNanos()));}if (gnssClock.hasFullBiasNanos()) {//如果存在接收机本地时钟总偏差,则显示builder.append(String.format(format, "总时钟偏差(FullBiasNanos)", gnssClock.getFullBiasNanos()));}if (gnssClock.hasBiasNanos()) {//亚纳秒偏差builder.append(String.format(format, "亚偏差(BiasNanos)", gnssClock.getBiasNanos()));}if (gnssClock.hasBiasUncertaintyNanos()) {//FullBiasNanos和BiasNanos的误差估计builder.append(String.format(format, "时钟偏差估计(BiasUncertaintyNanos)", numberFormat.format(gnssClock.getBiasUncertaintyNanos())));}/*** 注意:以上五个数据用于计算GPS时钟* 具体计算方法为:local estimate of GPS time = TimeNanos - (FullBiasNanos + BiasNanos)*     世界标准时:UtcTimeNanos = TimeNanos - (FullBiasNanos + BiasNanos) - LeapSecond * 1,000,000,000*/if (gnssClock.hasDriftNanosPerSecond()) {//以每秒纳秒为单位获取时钟的漂移builder.append(String.format(format, "时钟漂移(DriftNanosPerSecond)", numberFormat.format(gnssClock.getDriftNanosPerSecond())));}if (gnssClock.hasDriftUncertaintyNanosPerSecond()) {//时钟偏差的估计builder.append(String.format(format, "时钟漂移估计(DriftUncertaintyNanosPerSecond)", numberFormat.format(gnssClock.getDriftUncertaintyNanosPerSecond())));}//获取硬件时钟不连续的计数,即:每当gnssclock中断时,该值+1builder.append(String.format(format, "中断计数(HardwareClockDiscontinuityCount)", gnssClock.getHardwareClockDiscontinuityCount()));return builder.toString();}
private String toStringMeasurement(GnssMeasurement measurement){//将GNSS测量结果转换为字符串//定义显示格式final String format = "   %-4s = %s\n";StringBuilder builder = new StringBuilder("GNSS测量结果:\n");DecimalFormat numberFormat = new DecimalFormat("#0.000");DecimalFormat numberFormat1 = new DecimalFormat("#0.000E00");//获取卫星ID/*** 取决于卫星类型* GPS:1-32* SBAS:120-151、183-192* GLONASS:OSN或FCN + 100之一* 1-24作为轨道槽号(OSN)(首选,如果知道)* 93-106作为频道号(FCN)(-7至+6)加100。即将-7的FCN编码为93,0编码为100,+ 6编码为106* QZSS:193-200* 伽利略:1-36* 北斗:1-37*/builder.append(String.format(format, "卫星ID", measurement.getSvid()));//获取卫星类型/***  1:CONSTELLATION_GPS 使用GPS定位*  2:CONSTELLATION_SBAS 使用SBAS定位*  3:CONSTELLATION_GLONASS 使用格洛纳斯定位*  4:CONSTELLATION_QZSS 使用QZSS定位*  5:CONSTELLATION_BEIDOU 使用北斗定位 (^-^)!*  6:CONSTELLATION_GALILEO 使用伽利略定位*  7:CONSTELLATION_IRNSS 使用印度区域卫星定位*/builder.append(String.format(format, "卫星类型", measurement.getConstellationType()));//获取进行测量的时间偏移量(以纳秒为单位)builder.append(String.format(format, "测量时间偏移量", measurement.getTimeOffsetNanos()));//获取每个卫星的同步状态//具体数值含义请查表builder.append(String.format(format, "同步状态", measurement.getState()));//获取时间戳的伪距速率,以m/s为单位builder.append(String.format(format,"伪距速率",numberFormat.format(measurement.getPseudorangeRateMetersPerSecond())));//获取伪距的速率不确定性(1-Sigma),以m/s为单位builder.append(String.format(format,"伪距速率不确定度",numberFormat.format(measurement.getPseudorangeRateUncertaintyMetersPerSecond())));//if (measurement.getAccumulatedDeltaRangeState() != 0) {// 获取“累积增量范围”状态// 返回:MULTIPATH_INDICATOR_UNKNOWN(指示器不可用)=0// notice 即:指示器可用时,收集数据builder.append(String.format(format, "累积增量范围状态", measurement.getAccumulatedDeltaRangeState()));//获取自上次重置通道以来的累积增量范围,以米为单位.//该值仅在上面的state值为“可用”时有效//notice 累积增量范围= -k * 载波相位(其中k为常数)builder.append(String.format(format,"累积增量范围",numberFormat.format(measurement.getAccumulatedDeltaRangeMeters())));//获取以米为单位的累积增量范围的不确定性(1-Sigma)builder.append(String.format(format,"累积增量范围不确定度",numberFormat1.format(measurement.getAccumulatedDeltaRangeUncertaintyMeters())));}if (measurement.hasCarrierFrequencyHz()) {//获取被跟踪信号的载波频率builder.append(String.format(format, "信号载波频率", measurement.getCarrierFrequencyHz()));}if (measurement.hasCarrierCycles()) {//卫星和接收器之间的完整载波周期数builder.append(String.format(format, "载波周期数", measurement.getCarrierCycles()));}if (measurement.hasCarrierPhase()) {//获取接收器检测到的RF相位builder.append(String.format(format, "RF相位", measurement.getCarrierPhase()));}if (measurement.hasCarrierPhaseUncertainty()) {//误差估计builder.append(String.format(format, "RF相位不确定度", measurement.getCarrierPhaseUncertainty()));}//获取一个值,该值指示事件的“多路径”状态,返回0或1或2//MULTIPATH_INDICATOR_DETECTED = 1 测量显示有“多路径效应”迹象// MULTIPATH_INDICATOR_NOT_DETECTED = 2 测量结果显示没有“多路径效应”迹象builder.append(String.format(format, "多路经效应指示器", measurement.getMultipathIndicator()));//if (measurement.hasSnrInDb()) {//获取信噪比(SNR),以dB为单位builder.append(String.format(format, "信噪比", measurement.getSnrInDb()));}if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {if (measurement.hasAutomaticGainControlLevelDb()) {//获取以dB为单位的自动增益控制级别builder.append(String.format(format, "自动增益控制级别", measurement.getAutomaticGainControlLevelDb()));}if (measurement.hasCarrierFrequencyHz()) {builder.append(String.format(format, "载波频率", measurement.getCarrierFrequencyHz()));}}return builder.toString();}

最后将这些方法整合起来即可,UI显示的部分就不再赘述了。
关于伪距如何计算见下一篇博客:通过GNSS原始数据计算伪距

Android 获取GNSS原始数据相关推荐

  1. Android手机GNSS原始观测量

    Android手机GNSS原始观测值 随着谷歌开放了Android手机GNSS原始观测值数据获取接口,使得测绘领域中高精数据处理手段如(RTD/RTK/PPP)在智能手机的应用成为了可能,有望进一步提 ...

  2. android屏幕密度高度,Android获取常用辅助方法(获取屏幕高度、宽度、密度、通知栏高度、截图)...

    我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现.下面就分享一下Android中常用的一些辅助方法: 获取屏幕高度: /** * 获得屏幕高度 * @para ...

  3. Android获取当前时间

    2019独角兽企业重金招聘Python工程师标准>>> Android获取当前时间 2012-01-09 17:29:55|  分类: 私人日志 |字号 订阅 [转自stay] 取得 ...

  4. Android获取设备状态栏status bar高度的正确姿势

    Android获取设备状态栏高度的正确姿势 正确代码方式: int height = 0;int resourceId = getApplicationContext().getResources() ...

  5. 格式android id,android 获取APP的唯一标识applicationId的实例

    使用getIdentifier()方法可以方便的获各应用包下的指定资源ID. 方式一 int indentify = getResources().getIdentifier("com.te ...

  6. android 获取图片

    Android获取手机或者内存卡里面的图片有两种方式 1.这是通过一种action Intent intent=new Intent();intent.setAction(Intent.ACTION_ ...

  7. android 获取短信验证码倒计时

     android 获取短信验证码倒计时 public class MainActivity extends Activity { private Button submit;     privat ...

  8. [置顶] Android代码----android获取3G或wifi流量信息

    android获取3G或wifi流量信息: IBatteryStats battryStats = IBatteryStats.Stub.asInterface(ServiceManager.getS ...

  9. android 获取视频缩略图终极解决方案(ffmpeg)

    android 获取视频缩略图终极解决方案(ffmpeg) 参考文章: (1)android 获取视频缩略图终极解决方案(ffmpeg) (2)https://www.cnblogs.com/juka ...

最新文章

  1. CSS中的一些常见标签
  2. 卷积神经网络:VGG16 是基于大量真实图像的 ImageNet 图像库预训练的网络
  3. SQL Server 创建约束图解 唯一 主键
  4. java中compare语句的用法_Java RuleBasedCollator compare()用法及代码示例
  5. java web登录action_JavaWeb中登陆功能
  6. JEE7:展望新时代
  7. 《大道至简》第二章读后感
  8. 如何实现用户认证授权系统
  9. C# WPD PortableDeviceApiLib获取便携设备列表
  10. Mac上功能强大图片查看编辑工具:zGallery
  11. 获取Access数据库字段的所有属性(转)
  12. java list indexof_Java LinkedList indexOf()方法
  13. (zz)楚王何故好细腰
  14. android arcgis缓存,ArcGis for android 加载tpk离线文件
  15. matlab ode45修改,matlab ode45增加输入值
  16. 机器学习总结(九):梯度消失(vanishing gradient)与梯度爆炸(exploding gradient)问题
  17. ubuntu server 14.04 编译安装xen4.4.2配置vtpm(二)——Dom0内核编译
  18. Matplotlib数据可视化高级
  19. 硝基苯并-2-氧杂-1,3二唑(Nitrobenz-2-oxa-1,3-diazole,NBD)修饰BODIPY荧光探针检测GSH
  20. 【RAC】关闭Clusterware 遇到CRS-2529,ORA-15097:

热门文章

  1. 机器学习越来越火!免费查找AI最优论文神器出现啦!
  2. esp8266制作NFC电子门锁支持手机控制
  3. 【WEB】PHP代码分析溯源(PHP文件包含)
  4. 基于FPGA的等精度频率计,频率测量范围0~25M正弦波(方波),相位测量范围0~100k
  5. 编译原理课后习题答案清华大学出版社第二版
  6. java计算机毕业设计家装建材网源程序+mysql+系统+lw文档+远程调试
  7. 模拟键盘按键 c语言程序,C#实现的三种方式实现模拟键盘按键
  8. 嵌入式Linux应用开发——Linux下的C编程基础
  9. c语言 文件管理FILE
  10. 041:vue+openlayers读取WKT数据,输出GML、Polyline、GeoJSON(代码示例)