Android 监听卫星导航系统状态及卫星测量数据变化

在这里插入图片描述
源码

package com.android.circlescalebar;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.GnssClock;
import android.location.GnssMeasurement;
import android.location.GnssMeasurementsEvent;
import android.location.GnssStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.TextView;
import android.widget.Toast;
import com.android.circlescalebar.data.GnssRawData;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

public class GpsActivity extends AppCompatActivity {

    public static final int LOCATION_CODE = 525;
    private LocationManager locationManager;
    private String locationProvider = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gps);
        getLocation();
        GnssTest();
    }

    private void getLocation() {
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        //获取所有可用的位置提供器
        List<String> providers = locationManager.getProviders(true);

        if (providers.contains(LocationManager.GPS_PROVIDER)) {
            //如果是GPS
            locationProvider = LocationManager.GPS_PROVIDER;
        } else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
            //如果是Network
            locationProvider = LocationManager.NETWORK_PROVIDER;
        } else {
            Intent i = new Intent();
            i.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(i);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //获取权限(如果没有开启权限,会弹出对话框,询问是否开启权限)
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                //请求权限
                ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION,
                        android.Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_CODE);
            } else {
                //监视地理位置变化
                locationManager.requestLocationUpdates(locationProvider, 3000, 1, locationListener);
                Location location = locationManager.getLastKnownLocation(locationProvider);
                if (location != null) {
                    //输入经纬度
                    Toast.makeText(this, location.getLongitude() + " " + location.getLatitude() + "", Toast.LENGTH_SHORT).show();
                }
            }
        } else {
            //监视地理位置变化
            locationManager.requestLocationUpdates(locationProvider, 3000, 1, locationListener);
            Location location = locationManager.getLastKnownLocation(locationProvider);
            if (location != null) {
                //不为空,显示地理位置经纬度
                Toast.makeText(this, location.getLongitude() + " " + location.getLatitude() + "", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void GnssTest() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        locationManager.registerGnssStatusCallback(mGNSSCallback, null); //卫星导航系统的状态发生变化时被调用
        locationManager.registerGnssMeasurementsCallback(mGnssMeasurementsListener, null); //卫星测量数据
        // 请求位置跟新,所有监听器的回调都必须通过此方法
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, locationListener);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case LOCATION_CODE:
                if (grantResults.length > 0 && grantResults[0] == getPackageManager().PERMISSION_GRANTED
                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "申请权限", Toast.LENGTH_LONG).show();
                    try {
                        List<String> providers = locationManager.getProviders(true);
                        if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
                            //如果是Network
                            locationProvider = LocationManager.NETWORK_PROVIDER;
                        } else if (providers.contains(LocationManager.GPS_PROVIDER)) {
                            //如果是GPS
                            locationProvider = LocationManager.GPS_PROVIDER;
                        }
                        //监视地理位置变化
                        locationManager.requestLocationUpdates(locationProvider, 3000, 1, locationListener);
                        Location location = locationManager.getLastKnownLocation(locationProvider);
                        if (location != null) {
                            //不为空,显示地理位置经纬度
                            Toast.makeText(GpsActivity.this, location.getLongitude() + " " + location.getLatitude() + "", Toast.LENGTH_SHORT).show();
                        }
                    } catch (SecurityException e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(this, "缺少权限", Toast.LENGTH_LONG).show();
                    finish();
                }
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        locationManager.removeUpdates(locationListener);
    }

    public LocationListener locationListener = new LocationListener() {
        // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
        // Provider被enable时触发此函数,比如GPS被打开
        @Override
        public void onProviderEnabled(String provider) {
        }
        // Provider被disable时触发此函数,比如GPS被关闭
        @Override
        public void onProviderDisabled(String provider) {
        }
        //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
        @Override
        public void onLocationChanged(Location location) {
            if (location != null) {
                //不为空,显示地理位置经纬度
                Toast.makeText(GpsActivity.this, location.getLongitude() + " " + location.getLatitude() + "", Toast.LENGTH_SHORT).show();
            }
        }
    };

    GnssStatus.Callback mGNSSCallback = new GnssStatus.Callback() {
        @Override
        public void onSatelliteStatusChanged(@NonNull GnssStatus status) {
            super.onSatelliteStatusChanged(status);
            // get satellite count
            int satelliteCount = status.getSatelliteCount();
            int BDSatelliteCount = 0;
            int BDSInFix = 0;

            TextView sateCount = findViewById(R.id.sateCount);
            TextView satebeidou = findViewById(R.id.satebeidou);
            TextView satebeidoulocation = findViewById(R.id.satebeidoulocation);

            sateCount.setText("共收到卫星信号:" + satelliteCount + "个");

            if(satelliteCount > 0) {
                for (int i = 0; i < satelliteCount; i++) {
                    // get satellite type
                    int type = status.getConstellationType(i);
                    if(GnssStatus.CONSTELLATION_BEIDOU == type) {
                        // increase if type == BEIDOU
                        BDSatelliteCount++;
                        if (status.usedInFix(i)) {
                            BDSInFix++;
                        }
                    }
                }
                satebeidou.setText("北斗卫星有:" + BDSatelliteCount + "个");
                satebeidoulocation.setText("用于定位的北斗卫星有:" + BDSInFix + "个");
            }
        }
    };


    private final GnssMeasurementsEvent.Callback mGnssMeasurementsListener = new GnssMeasurementsEvent.Callback() {
        @Override
        public void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) {
            super.onGnssMeasurementsReceived(eventArgs);
            GnssClock clock = eventArgs.getClock();
            Collection<GnssMeasurement> measurements = eventArgs.getMeasurements();
            List<Mea> mLst = new ArrayList<>();
            for (GnssMeasurement measurement : measurements) {
                GnssRawData data = new GnssRawData(measurement, clock);
                mLst.add(new Mea(data.getPRN(), data.getCarrierFrequencyHZ(), data.getPseudorange(),
                        clock.getTimeNanos(), clock.getFullBiasNanos(), measurement.getReceivedSvTimeNanos()));
            }
            Collections.sort(mLst);
            StringBuilder builder = new StringBuilder();
            Locale locale = Locale.getDefault();
            builder.append(String.format(locale, "%5s%20s%20s\n", "SV", "Carrier(MHz)", "Value"));
            for (Mea m : mLst) {
                builder.append(String.format(locale, "%5s%20.3f%20.3f\n", m.getPRN(),
                        m.getCarrier(), m.getPseudorange()));
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    TextView sate = findViewById(R.id.sate);
                    sate.setText(builder.toString());
                }
            });
        }

        @Override
        public void onStatusChanged(int status) {
            super.onStatusChanged(status);
        }
    };

    /**
     * 将 measurement排序(为了查看是否有多频)
     */
    class Mea implements Comparable<Mea> {
        private final String prn;
        private final double carrier;
        private final double pseudorange;
        private final double TimeNanos;
        private final double FullBiasNanos;
        private final double ReceivedSvTimeNanos;

        public Mea(String prn, double carrier, double pseudorange, double TimeNanos,
                   double FullBiasNanos, double ReceivedSvTimeNanos) {
            this.prn = prn;
            this.carrier = carrier;
            this.pseudorange = pseudorange;
            this.TimeNanos = TimeNanos;
            this.FullBiasNanos = FullBiasNanos;
            this.ReceivedSvTimeNanos = ReceivedSvTimeNanos;
        }

        @Override
        public int compareTo(Mea o) {
            return this.prn.compareTo(o.prn);
        }

        public String getPRN() {
            return prn;
        }

        public double getCarrier() {
            return carrier;
        }

        public double getPseudorange() {
            return pseudorange;
        }

        public double getTimeNanos() {
            return TimeNanos;
        }

        public double getFullBiasNanos() {
            return FullBiasNanos;
        }

        public double getReceivedSvTimeNanos() {
            return ReceivedSvTimeNanos;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/459255.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

雷达水位监测站在水资源管理中的重要性及应用

TH-SW1&#xff0c;随着全球气候变化和水资源日益紧张&#xff0c;对水资源进行有效管理变得至关重要。雷达水位监测站作为一种先进的水位监测设备&#xff0c;在水资源管理中发挥着越来越重要的作用。 一、雷达水位监测站的工作原理 雷达水位监测站利用雷达技术&#xff0c;通…

WRF模型教程(ububtu系统)-WPS(WRF Pre-Processing System)概述

一、WPS简介 WRF 预处理系统 (WRF Pre-Processing System&#xff0c;WPS) &#xff0c;集成了基于Fortran和C编写的程序&#xff0c;这些程序主要用于处理输入到real.exe的数据。WPS主要有三个程序和一些辅助程序。 二、各程序介绍 主要的程序为geogrid.exe、ungrib.exe、met…

爬虫逆向实战(36)-某建设监管平台(RSA,魔改)

一、数据接口分析 主页地址&#xff1a;某建设监管平台 1、抓包 通过抓包可以发现网站首先是请求了一个/prod-api/mohurd-pub/vcode/genVcode的接口&#xff0c;用于获取滑块验证码的图片 滑块验证之后&#xff0c;请求了/prod-api/mohurd-pub/dataServ/findBaseEntDpPage这…

Golang 开发实战day04 - Standard Library

Golang 开发实战day04 - Standard Library 接下来开始我们第四天学习&#xff0c;Go语言标准库提供了丰富的功能&#xff0c;可以帮助开发者快速完成各种任务。 golang就像其他语言一样&#xff0c;附带了一些非常轻量级的函数和特性&#xff0c;都是开箱即用的&#xff0c;这里…

探索仿函数(Functor):C++中的灵活函数对象

文章目录 一、仿函数定义及使用二、仿函数与函数指针的区别三、仿函数与算法的关系四、仿函数的实践用例 在C编程中&#xff0c;我们经常需要对数据进行排序、筛选或者其他操作。为了实现这些功能&#xff0c;C标准库提供了许多通用的算法和容器&#xff0c;而其中一个重要的概…

AWS云上面的k8s统一日志收集(Fluent Bit+EKS+CW)

目标 k8s上面的常见的统一日志方案是EFK&#xff0c;具体如下&#xff1a; E:elasticsearch;F:fluentd;K:kibana 这里我们变成了使用fluentd的AWS替代品Fluent Bit&#xff0c;直接将日志输出到CloudWatch组。不需要E和K了。不过&#xff0c;这样仅仅用于AWS EKS。 步骤 给…

【C语言】字符与字符串---从入门到入土级详解

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 一.字符类型和字符数组&#xff08;串&#xff09;简介 1.ASCII 2.定义&#xff0c;初始化&#xff0c;使用 1>字符的定义及初始化 2>字符串的定义及初始化 二.…

Linux——信号量

目录 POSIX信号量 信号量原理 信号量概念 信号量函数 基于环形队列的生产者消费者模型 生产者和消费者申请和释放资源 单生产者单消费者 多生产者多消费者 多生产者多消费者的意义 信号量的意义 POSIX信号量 信号量原理 如果仅用一个互斥锁对临界资源进行保护&#…

19.ADC模数转换器知识点+AD单通道AD多通道应用程序示例

0. 江协科技/江科大-STM32标准库开发-各章节详细笔记-查阅传送门_江协科技stm32笔记-CSDN博客文章浏览阅读2.9k次&#xff0c;点赞44次&#xff0c;收藏128次。江协科技/江科大-STM32标准库开发-各章节详细笔记-传送门至各个章节笔记。基本上课程讲的每句都详细记录&#xff0c…

PHP微信朋友圈广告植入源码 – 提供高效的广告植入解决方案,助力微信朋友圈广告推广

内容介绍 管理后台 可以无限制帮用户开户&#xff0c;也可以理解为多用户版。 可以管理用户发布文章条数&#xff0c;也可以无限制发布。 前端用户 用户可以上传多个广告&#xff0c;每个广告分别进行统计展示及点击。 用户一键植入&#xff0c;不用粘贴网址&#xff0c;每篇…

Spring Security自定义认证授权过滤器

自定义认证授权过滤器 自定义认证授权过滤器1、SpringSecurity内置认证流程2、自定义Security认证过滤器2.1 自定义认证过滤器2.2 定义获取用户详情服务bean2.3 定义SecurityConfig类2.4 自定义认证流程测试 3、 基于JWT实现无状态认证3.1 认证成功响应JWT实现3.2 SpringSecuri…

从大厂到高校,鸿蒙人才“红透半边天”!

截至目前&#xff0c;继清华大学、北京航空航天大学、武汉大学等985高校开设鸿蒙相关课程后&#xff0c;已经或将要开设鸿蒙相关课程的985、211高校达到近百所&#xff0c;为鸿蒙人才培养提供沃土。 随着鸿蒙系统即将摒弃安卓&#xff0c;鸿蒙原生应用将全面启动的背景下&…

4款实用性前端动画特效分享(附在线演示)

分享4款非常不错的项目动画特效 其中有jQuery特效、canvas特效、CSS动画等等 下方效果图可能不是特别的生动 那么你可以点击在线预览进行查看相应的动画特效 同时也是可以下载该资源的 全屏图片视差旋转切换特效 基于anime.js制作全屏响应式的图片元素布局&#xff0c;通过左…

javaweb学习(day09-Web开发会话技术)

一、会话 1 基本介绍 1.1 什么是会话&#xff1f; 会话可简单理解为&#xff1a;用户开一个浏览器&#xff0c;点击多个超链接&#xff0c;访问服务器多个 web 资源&#xff0c;然 后关闭浏览器&#xff0c;整个过程称之为一个会话。 1.2 会话过程中要解决的一些问题&#…

[LVGL]:MACOS下使用LVGL模拟器

如何在MACOS下使用lvgl模拟器 1.安装必要环境 brew install sdl2查看sdl2安装位置&#xff1a; (base) ➜ ~ brew list sdl2 /opt/homebrew/Cellar/sdl2/2.30.1/bin/sdl2-config /opt/homebrew/Cellar/sdl2/2.30.1/include/SDL2/ (78 files) /opt/homebrew/Cellar/sdl2/2.3…

权威发布!艾媒咨询最新报告显示65.1%的消费者还在睡硬床

一直以来,“睡硬床好”观念在中国盛行,国民较多青睐硬床,床垫厂商为迎合大众,大批量生产硬床垫。日前,全球新经济产业第三方数据挖掘和分析机构iiMedia Research(艾媒咨询)发布《2024年中国硬床垫使用现状及潜在危害调研》(以下简称:报告),数据显示,75.1%的消费者对“睡硬床对腰…

DM数据库安装及使用(Windows、Linux、docker)

Windows 先解压安装包 点击setup安装 下一步 勾选接受然后下一步 下一步 选择典型安装下一步 下一步 搜索DM数据库配置助手然后一直下一步 然后搜索DM管理工具 登录 登录成功 widows版本安装成功 Linux安装 操作系统CPU数据库CentOS7x86_64 架构dm8_20230418_x86_rh6_64 …

Nacos源码流程图

1.Nacos1.x版本服务注册与发现源码 流程图地址&#xff1a;https://www.processon.com/view/link/634695eb260d7157a7bc6adb 2.Nacos2.x版本服务注册与发现源码 流程图地址&#xff1a;https://www.processon.com/view/link/634695fb260d7157a7bc6ae0 3.Nacos2.x版本GRPC…

【深度学习笔记】10_11 注意力机制

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 10.11 注意力机制 在10.9节&#xff08;编码器—解码器&#xff08;seq2seq&#xff09;&#xff09;里&#xff0c;解码器在各个时间…

Leet code 1658 将x减到0的最小操作数

解题思路&#xff1a;滑动窗口 主要思想&#xff1a;正难逆简 题目需要左找一个数 右找一个数 我们不如直接找中间最长的一连串子数让这串子树和为 数组子树和减去X 找不到就返回 -1 滑动窗口双指针从左端出发&#xff0c;进行 进窗口 判断 出窗口 更新结果四个步骤 代码…