Android - GPS的简单应用

这篇具有很好参考价值的文章主要介绍了Android - GPS的简单应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

关于GPS卫星信息的获取,网上很多类似文章但都是只能用于安卓7.0以下的,在这里将安卓7.0以下的方法和安卓7.0以上的方法做个总结,安卓7.0以下用GpsStatus.Listener,安卓7.0及以上版本用GnssStatus.Callback


一、定位信息获取:LocationListener

1.创建位置信息监听器LocationListener

系统已经提供了LocationListener类,所以我们使用时直接实现它,重写下里面的几个方法就可以了,这里重点记录onLocationChanged()方法,这个方法有一个参数对象location,location里面记录了当前位置信息的所有数据,以下代码中在location中获取了经纬度和时间,location还有其他信息具体可参考API

    //当位置发生变化时自动调用
    @Override
    public void onLocationChanged(@NonNull Location location) {
        double longitude = location.getLongitude();     //获取当前位置信息的经度
        double latitude = location.getLatitude();       //获取当前位置信息的纬度

        //获取卫星时间
        long SatelliteTime = location.getTime();
        String time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(SatelliteTime);


    }

    //当提供者状态改变时调用。 当提供者无法获取位置或提供者最近在不可用时段后变为可用时,将调用此方法。
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    //当提供者被用户启用时调用。
    @Override
    public void onProviderEnabled(String provider) {

    }

    //当提供者被用户禁用时调用。 如果在已禁用的提供程序上调用requestLocationUpdates,则立即调用此方法。
    @Override
    public void onProviderDisabled(String provider) {

    }


2.打开监听器开始监听

LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, (LocationListener) this);

3.关闭监听器停止监听

manager.removeUpdates(this);

二、卫星信息获取:GpsStatus.Listener

仅安卓7.0以下可用,安卓7.0以上的版本要用GnssStatus.Callback

1.创建GpsStatus.Listener监听器

同样系统已经提供了GpsStatus.Listener,只需要实现它重写onGpsStatusChanged方法就可以了,GpsStatus.Listener监听器获取的数据存储在GpsSatellite对象中

	@Override
    public void onGpsStatusChanged(int event) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        GpsStatus ges = manager.getGpsStatus(null);      //获取GPS状态
        switch (event) {
            case GpsStatus.GPS_EVENT_FIRST_FIX:
                break;
            //定期发送事件以报告 GPS 卫星状态。
            case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                Iterable<GpsSatellite> lis = ges.getSatellites();       //获取卫星信息迭代数组
                Iterator it = lis.iterator();

                while (it.hasNext()) {
                    GpsSatellite s = (GpsSatellite) it.next();
                    float id = s.getSnr();     //卫星id
                    float DBHz = s.getSnr();     //卫星信号强度
                    float azimuthDegrees = s.getAzimuth();  //卫星方位角
                    boolean infix = s.usedInFix();  //卫星是否可用于定位
                    float elevationDegrees = s.getElevation();     //卫星高程
                    boolean almanacData =s.hasAlmanac();   //卫星是否具有年历数据
                    boolean ephemerisData = s.hasEphemeris();      //卫星是否具有星历数据
                }
                break;
            case GpsStatus.GPS_EVENT_STARTED:
                break;
            case GpsStatus.GPS_EVENT_STOPPED:
                break;
            default:
                break;
        }
    }

2.打开监听器

manager.addGpsStatusListener(this::onGpsStatusChanged);

3.关闭监听器

manager.removeGpsStatusListener(this);

三、卫星信息获取:GnssStatus.Callback

1.注册GnssStatus.Listener监听器

GnssStatus.Listener监听器获取的卫星数据存储在GnssStatus对象中

GnssStatus.Callback gnsscallback = new GnssStatus.Callback() {
        //定期调用以报告GNSS卫星状态
        @Override
        public void onSatelliteStatusChanged(GnssStatus status) {
            //总数量
            hhstar1 = status.getSatelliteCount();
            //如果卫星总数大于0
            if (status != null && status.getSatelliteCount() > 0) {
            
                //循环遍历卫星
                for (int i = 0; i < status.getSatelliteCount(); i++) {
                    int id = status.getSvid(i);     //卫星id
                    float DBHz = status.getCn0DbHz(i);     //卫星信号强度
                    int type = status.getConstellationType(i);       //卫星星座类型
                    float azimuthDegrees = status.getAzimuthDegrees(i);  //卫星方位角
                    boolean infix = status.usedInFix(i);  //卫星是否可用于定位
                   	float elevationDegrees = status.getElevationDegrees(i);     //卫星高程
                    boolean almanacData =status.hasAlmanacData(i);   //卫星是否具有年历数据
                    boolean ephemerisData = status.hasEphemerisData(i);      //卫星是否具有星历数据
                    }
                }
            }
        }
    };

2.打开监听器

 manager.registerGnssStatusCallback(gnsscallback, null);

3.关闭监听器

manager.unregisterGnssStatusCallback(gnsscallback);

四、两种卫星获取方式对比

1.卫星号不同

GpsSatellite:获取到的数据中,卫星号是PRN,每颗卫星都有一个唯一的PRN码,我们可以通过PRN码来确定它是什么类型的卫星,这里简单介绍一下:
1-32:GPS卫星
33-64:GPS的备用卫星和测试卫星
65-96:GLONASS卫星
193-200:QZSS卫星
201-261:北斗卫星
301-336:伽利略卫星
901-918:IRNSS卫星

GnssStatus:获取到的数据中没有PRN,但是它有一个Svid和ConstellationType,这个Svid不同的卫星有可能会重复,就是如果获取到两颗卫星,一颗GPS一颗北斗他们的Svid可能是一样的,所以无法判断它是哪种卫星,要通过获取数据中的ConstellationType来判断它是GPS还是北斗,下面介绍一下这个对象中北斗和GPS卫星的Svid范围和ConstellationType的常量
1-32:GPS卫星
1-37:北斗卫星
GnssStatus数据中,如果获取到的卫星号是1-32,那么它可能是GPS也有可能是北斗,所以还要获取ConstellationType数据也就是星座类型标识符
GPS: CONSTELLATION_GPS		常量值为1
北斗:CONSTELLATION_BEIDOU	常量值为5

2. 信号值不同

GpsSatellite:信号值叫信噪比,单位是db
GnssStatus:信号值叫载噪比,单位是dB-Hz
信噪比和载噪比都是代表卫星信号强度,他们具体有什么区别自行探索

3. 对象中的数据对比

整体来说GnssStatus比GpsSatellite多了两个数据:
1.GnssStatus可以获取搜索到的卫星总数,GpsSatellite不行
2.GnssStatus多了一个区分卫星星座类型的参数,GpsSatellite没有

五、实例代码

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
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.pm.PackageManager;
import android.location.GnssStatus;
import android.location.GpsSatellite;
import android.location.GpsStatus;
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.util.Log;
import android.widget.Toast;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;

public class MainActivity extends AppCompatActivity implements LocationListener, GpsStatus.Listener {
    private LocationManager manager;
    private GnssStatus.Callback gnsscallback;

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

    //动态权限申请
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1: {
                for (int i = 0; i < permissions.length; i++) {
                    if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        Toast.makeText(this, "权限已打开!", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }

/*
***************************************实现LocationListener重写的方法********************************
 */
    //当位置发生变化时自动调用
    @Override
    public void onLocationChanged(@NonNull Location location) {
        double longitude = location.getLongitude();     //获取当前位置信息的经度
        double latitude = location.getLatitude();       //获取当前位置信息的纬度

        //获取卫星时间
        long SatelliteTime = location.getTime();
        String time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(SatelliteTime);
    }

    //当提供者状态改变时调用。 当提供者无法获取位置或提供者最近在不可用时段后变为可用时,将调用此方法。
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }
    //当提供者被用户启用时调用。
    @Override
    public void onProviderEnabled(String provider) {

    }
    //当提供者被用户禁用时调用。 如果在已禁用的提供程序上调用requestLocationUpdates,则立即调用此方法。
    @Override
    public void onProviderDisabled(String provider) {

    }

/*
***************************************************实现GpsStatus.Listener重写的方法************************************************************
 */
    @Override
    public void onGpsStatusChanged(int event) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        GpsStatus ges = manager.getGpsStatus(null);      //获取GPS状态
        switch (event) {
            //GPS系统自启动以来收到第一次修复时发送的事件
            case GpsStatus.GPS_EVENT_FIRST_FIX:
                break;
            //定期发送事件以报告 GPS 卫星状态。
            case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                Iterable<GpsSatellite> lis = ges.getSatellites();       //获取卫星信息迭代数组
                Iterator it = lis.iterator();

                while (it.hasNext()) {
                    GpsSatellite s = (GpsSatellite) it.next();

                    float id = s.getSnr();     //卫星id
                    float DBHz = s.getSnr();     //卫星信号强度
                    float azimuthDegrees = s.getAzimuth();  //卫星方位角
                    boolean infix = s.usedInFix();  //卫星是否可用于定位
                    float elevationDegrees = s.getElevation();     //卫星高程
                    boolean almanacData =s.hasAlmanac();   //卫星是否具有年历数据
                    boolean ephemerisData = s.hasEphemeris();      //卫星是否具有星历数据

                }
                break;
            //GPS系统启动时发送的事件
            case GpsStatus.GPS_EVENT_STARTED:
                break;
            //GPS系统停止时发送的事件
            case GpsStatus.GPS_EVENT_STOPPED:
                break;
            default:
                break;
        }
    }

/*
*******************************************创建GnssStatus.Callback******************************************************************
 */
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void createGnssStatusCallback() {
        gnsscallback = new GnssStatus.Callback() {
            //定期调用以报告GNSS卫星状态
            @Override
            public void onSatelliteStatusChanged(GnssStatus status) {

                //卫星总数量
                int number = status.getSatelliteCount();
                Log.d("MainActivity", number + "颗");
                //如果卫星总数大于0
                if (status != null && status.getSatelliteCount() > 0) {
                    //循环遍历status提取卫星信息
                    for (int i = 0; i < status.getSatelliteCount(); i++) {

                        int id = status.getSvid(i);     //卫星id
                        float DBHz = status.getCn0DbHz(i);     //卫星信号强度
                        int type = status.getConstellationType(i);       //卫星星座类型
                        float azimuthDegrees = status.getAzimuthDegrees(i);  //卫星方位角
                        boolean infix = status.usedInFix(i);  //卫星是否可用于定位
                        float elevationDegrees = status.getElevationDegrees(i);     //卫星高程
                        boolean almanacData =status.hasAlmanacData(i);   //卫星是否具有年历数据
                        boolean ephemerisData = status.hasEphemerisData(i);      //卫星是否具有星历数据
                    }
                }
            }
        };
    }

    @Override
    protected void onResume() {
        super.onResume();
        manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        //判断权限是否已打开
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
        }
        //判断GPS是否已打开
        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Settings.Secure.putInt(MainActivity.this.getContentResolver(), Settings.Secure.LOCATION_MODE, 3);       //自动打开GPS开关
        }

        //添加GPS定位信息监听器
        manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this);

        //获取卫星信息的方法在安卓7.0以前使用GpsStatus.Listener,安卓7.0及以后的版本只能用GnssStatus.Callback,在这里判断安卓SDK的版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            createGnssStatusCallback();
            manager.registerGnssStatusCallback(gnsscallback, null);
        } else {
            manager.addGpsStatusListener(this);
        }
    }

    @Override
    public void onPause() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            manager.unregisterGnssStatusCallback(gnsscallback);
        } else {
            manager.removeGpsStatusListener(this);
        }
        manager.removeUpdates(this);

        super.onPause();
    }

    @Override
    public void onDestroy() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            manager.unregisterGnssStatusCallback(gnsscallback);
        } else {
            manager.removeGpsStatusListener(this);
        }
        manager.removeUpdates(this);
        super.onDestroy();
    }
}

最后不要忘了申请权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

总结

就这么点东西学习的时候硬是耗了我好几个日夜,学会之后发现其实很简单文章来源地址https://www.toymoban.com/news/detail-757172.html

到了这里,关于Android - GPS的简单应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android cpu信息获取/修改

    通过 cat proc/cpuinfo 查看 应用端,类似某兔兔中CPU信息应该也是从这里获取的  cpuinfo 文件内容是在 kernel/msm-4.19/arch/arm64/kernel/cpuinfo.c 中 c_show 函数中写入的 注:上面 arch_read_hardware_id 函数,高通平台是在 kernel/msm-4.19/drivers/soc/qcom/socinfo.c 文件中,等于 msm_read_hardware_id 函数 这

    2024年02月12日
    浏览(35)
  • android adb 获取电池信息以及设置

    本文主要包含 1、设置adb 无线调试桥连接步骤 2、打印设备电池状态(当前电量、充电状态、充放电电流大小、电池种类等) 3、更改电池充电状态、电量百分比、电池还原命令 4、断开adb 远程调试桥 -------------------------------------------------------------------------------- 详细步骤如下

    2024年02月14日
    浏览(37)
  • 【Android开发基础】蓝牙信息的获取(Bluetooth)

    描述:蓝牙技术是一种无线数据和语音通信开放的全球规范,它是基于低成本的近距离无线连接,为固定和移动设备建立通信环境的一种特殊的近距离无线技术连接。蓝牙使当前的一些便携移动设备和计算机设备能够不需要电缆就能连接到互联网,并且可以无线接入互联网。

    2024年02月09日
    浏览(40)
  • android开发获取手机麦克风设备信息

    之前为了测试蓝牙耳机的麦克,想从蓝牙耳机的麦克录音。尝试发现三星、小米自带的录音机并不能从蓝牙录音。看了网上一篇文章,提供了一个特定的录音APP,才支持开启蓝牙录音功能。 非常令人疑惑。想到现在的手机,有不只一个麦克风,是否能开发一个可选择录音源的

    2024年04月16日
    浏览(44)
  • Android 手机来电 获取来电信息,接听/挂断电话

    目录 1.需求描述 2.实现原理 第一个:手机来电状态 第二个:获取手机来电号码 第三个:接听和挂断电话 1.需求描述 监听用户手机来电,弹起App内自定义的来电展示,并且展示来电电话,用户可以接通和挂断。 2.实现原理 这儿我就总结下手机来电、获取手机号码和接听/挂断

    2024年02月12日
    浏览(51)
  • Android 获取手机通讯录联系人信息

    近日在项目开发过程中发现,华为手机HarmonyOS 3.0系统,设置隐私 里面可以查看各个应用访问隐私权限的次数,发现应用程序访问手机通讯录的次数异常的高,针对访问通讯录频次高的问题做了研究和优化 问题分析: 分析代码发现只要通过ContentProvider 访问通讯录一次,统计

    2024年02月12日
    浏览(44)
  • 【Android开发基础】手机传感器信息的获取

    描述:关于传感器的使用,我在同栏目下发了一篇关于传感器(方向传感器、加速度传感器)的使用,这篇博客主要以获取不同手机所支持的传感器信息为主,具体如何使用这些传感器,需要自己进行查阅和学习,也可以私聊我。 博客:传感器(方向传感器、加速度传感器)

    2024年02月10日
    浏览(99)
  • Android中获取手机SIM卡的各种信息

     通过以下工具类方法可以获取到手机SIM的各种信息数据!!!

    2024年02月10日
    浏览(38)
  • Android项目获取网页信息的三种方法

    具体操作可以参考我的另一篇文章eclipse创建Android项目调用jsoup获取网页信息 进入想要获取信息的网页,点击F12进入开发者模式,选择网络,刷新页面,点击标头,参考对应字条,没有的字条就不修改。

    2024年02月15日
    浏览(93)
  • 基于scrcpy的Android群控项目重构,获取Android屏幕元素信息并编写自动化事件

    基于scrcpy的远程调试方案 基于scrcpy的Android群控项目重构 基于scrcpy的Android群控项目重构 进阶版 基于scrcpy的Android群控项目重构,获取Android屏幕元素信息并编写自动化事件(视频) 基于scrcpy的Android群控项目重构,获取Android屏幕元素信息并编写自动化事件(博客) 基于scrcpy的

    2024年02月16日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包