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

news2025/1/16 5:35:32

在这里插入图片描述
源码

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.coloradmin.cn/o/1519256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用数据驱动的MEG分析方法提取fMRI静息态网络

摘要 静息态网络(RSN)的电生理基础仍存在争议。特别是&#xff0c;尚未确定一个能够同样有效解释所有静息态网络的原理性机制。虽然脑磁图(MEG)和脑电图(EEG)是确定RSN电生理基础的首选方法&#xff0c;但目前没有标准的RSN分析流程。本文比较了从MEG数据中提取RSNs的两种现有…

跨境热点!TikTok直播网络要求是什么?

TikTok直播作为一种互动性强、实时性要求高的社交媒体形式&#xff0c;对网络环境有着一系列特定的需求。了解并满足这些需求&#xff0c;对于确保用户体验、提高直播质量至关重要。本文将深入探讨TikTok直播对网络环境的要求以及如何优化网络设置以满足这些要求。 TikTok直播的…

git小白入门

git是什么 Git是一种流行的版本控制系统&#xff0c;被广泛用于软件开发中来跟踪和管理代码的变化。它是由Linus Torvalds在2005年创建的&#xff0c;最初的目的是为了更高效地管理Linux内核的开发。Git使得多人在同一个项目上工作变得更加简单&#xff0c;可以轻松合并不同开…

跨域问题经典解决方法

这里写目录标题 背景步骤m3u8文件是什么&#xff1f;&#xff1f;本地播放m3u8文件在浏览器上播放m3u8视频跨域问题什么是跨域问题&#xff1f;为什么有跨域问题&#xff1f;如何解决跨域问题&#xff1f;使用代理服务器CORS&#xff08;跨域资源共享&#xff09; 总结 背景 同…

[JavaWeb学习日记]Vue工程,springboot工程整合Mybatis,数据库索引

目录 一.Vue工程 安装NodeJS与Vue-cli Vue项目创建 启动Vue项目&#xff1a;点击npm脚本serve 改端口&#xff1a;在vue.config.js下 Vue文件组成&#xff1a;templatescriptstyle 使用element 前端服务器当前使用Ngix 主要编写的文件 二.SpringBoot的Web工程 启动带…

2024.3.15每日一题

LeetCode 卖木头块 题目链接&#xff1a;2312. 卖木头块 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你两个整数 m 和 n &#xff0c;分别表示一块矩形木块的高和宽。同时给你一个二维整数数组 prices &#xff0c;其中 prices[i] [hi, wi, pricei] 表示你可以以…

被问了N遍的效率工具!批量自动添加好友

你还在手动输入客户号码或是微信号&#xff0c;再逐一进行搜索和添加吗&#xff1f; 现在有一个工具可以帮助你完成这项重复枯燥的工作任务&#xff0c;而且&#xff0c;这个工具不仅能够帮助你批量添加微信好友&#xff0c;更有很多自动化的功能&#xff0c;让你的办公效率得…

C语言宏定义问题

C语言中&#xff0c;在定义数组时&#xff0c;因为数组长度需要是常量或者宏&#xff0c;尝试将变量按照值不同定义同一个宏的不同值&#xff0c;然后用宏来定义数组长度&#xff0c;结果发现不行。原来C的宏定义&#xff0c;是不能重复的&#xff0c;下面是ChatGPT给的答案&am…

【HyperLips:】数字人——控制嘴唇 项目源码python实现

最近受到商汤“复活”汤晓鸥的视频刺激&#xff0c;大大的amazing&#xff01;没看过的小伙伴可以自行百度&#xff0c;看了不研究一下【数字人】技术&#xff0c;都要跟时代脱轨了&#xff0c;那就以HyperLips为开篇吧。 目录 &#x1f34e;&#x1f34e;1.摘要 &#x1f3…

python创建虚拟环境-Anaconda安装配置和使用

Anaconda提供了一个名为conda的包管理工具&#xff0c;可以方便地创建、管理和分享Python环境。用户可以根据自己的需要创建不同的环境&#xff0c;每个环境都可以拥有自己的Python版本、库和依赖项&#xff0c;这样就可以避免因为不同项目之间的依赖关系而导致的冲突问题。 一…

数据集成平台选型建议

一 数据集成介绍 数据集成平台是一种用于管理和协调数据流动的软件工具或服务。它的主要目标是将来自多个不同数据源的数据整合到一个统一的、易于访问和分析的数据存储库中。这些数据源可以包括数据库、云应用、传感器、日志文件、社交媒体等等。数据集成平台的关键任务是确保…

外卖平台订餐流程架构的实践

当我们想要在外卖平台上订餐时&#xff0c;背后其实涉及到复杂的技术架构和流程设计。本文将就外卖平台订餐流程的架构进行介绍&#xff0c;并探讨其中涉及的关键技术和流程。 ## 第一步&#xff1a;用户端体验 用户通过手机应用或网页访问外卖平台&#xff0c;浏览菜单、选择…

数字信封

一、概念 数字信封是将对称密钥通过非对称加密&#xff08;即&#xff1a;有公钥和私钥两个&#xff09;的结果分发对称密钥的方法。数字信封是实现信息保密性验证的技术。 二、过程描述 在数字信封中&#xff0c;信息发送方采用对称密钥来加密信息内容&#xff0c;然后将此…

nut-ui组件库icon中使用阿里图标

1.需求 基本每个移动端组件库都有组件 icon组件 图标组件、 但是很多组件库中并找不到我们需要的图标 这时候 大家有可能会找图标库 最大众的就是iconfont的图标了 2.使用 有很多方式去使用这个东西 比如将再限链接中的css引入 在使用 直接下载图标 symbol 方式 等....…

商家转账到零钱转账场景说明指导

商家转账到零钱是什么&#xff1f; 商家转账到零钱功能是指商家可以通过支付平台将资金直接转账到用户的零钱账户中。在这种情况下&#xff0c;商家不需要用户提供银行账户信息&#xff0c;而是使用支付平台的转账功能将资金直接转移到用户的零钱账户中。 商家转账到零钱的使…

SpringBoot(依赖管理和自动配置)

文章目录 1.基本介绍1.springboot是什么&#xff1f;2.快速入门1.需求分析2.环境配置1.确认开发环境2.创建一个maven项目3.依赖配置 pom.xml4.文件目录5.MainApp.java &#xff08;启动类&#xff0c;常规配置&#xff09;6.HelloController.java &#xff08;测试Controller&a…

基于DataX迁移MySQL到OceanBase集群

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

Windows中在C#中使用Dapper和Mysql.Data库连接MySQL数据库

Windows中在C#中使用Dapper和Mysql.Data库连接MySQL数据库 在Windows中使用C#连接Mysql数据库比较简单&#xff0c;可以直接使用MySql.Data库&#xff0c;目前最新版本为&#xff1a;8.3.0。 当然也可以结合MySql.Data和Dapper库一起使用&#xff0c;目前Dapper的最新版本为&a…

rancher里的ingress如何配置gzip压缩

方案一&#xff0c;未试验成功&#xff0c;但配置过程值得记录一下 通过配置configmap&#xff0c;然后在ingress的deployment里引用configmap实现。 参考文章 创建configmap apiVersion: v1 kind: ConfigMap metadata:name: nginx-ingress-controllerannotations:{} # k…

【C++算法模板】图论-拓扑排序,超详细注释带例题

文章目录 0&#xff09;概述1&#xff09;Kahn算法1&#xff1a;数据结构2&#xff1a;建图3&#xff1a;Kanh算法 2&#xff09;DFS染色1&#xff1a;数据结构2&#xff1a;建图3&#xff1a;DFS 3&#xff09;算法对比【例题】洛谷 B3644 推荐视频链接&#xff1a;D01 拓扑排…