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


源码

java 复制代码
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;
        }
    }
}
相关推荐
拭心5 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
带电的小王7 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡7 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道8 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库8 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道9 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe9 小时前
Android Hook - 动态加载so库
android
居居飒10 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He13 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗13 小时前
Android笔试面试题AI答之Android基础(1)
android