Android 定位获取nmea 数据

首先在 AndroidManifest.xml 清单文件中添加权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.INTERNET"/>

获取定位的activity或者service 继承

LocationListener, OnNmeaMessageListener, GpsStatus.NmeaListener

注意 OnNmeaMessageListener 和 GpsStatus.Listener 不能同时继承 ,就是要么继承 LocationListener, OnNmeaMessageListener, GpsStatus.NmeaListener ,要么继承 LocationListener, GpsStatus.NmeaListener, GpsStatus.NmeaListener 

获取LocationManager对象 

locationManager = (LocationManager) getSystemService(this.LOCATION_SERVICE);

检查isProviderEnabled()方法,LocationManager网络服务提供者是否启用

boolean providerEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

申请权限

/**
 * 权限组
 */
String[] permissionsGroup = new String[]{

        Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_BACKGROUND_LOCATION

};
if (providerEnabled) {//开启了定位权限
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        //没开启权限申请权限

        requestPermissions(permissionsGroup,10);

    } else {

        //有权限
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1,  this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            locationManager.addNmeaListener((OnNmeaMessageListener) this);

        } else {
            locationManager.addNmeaListener((GpsStatus.NmeaListener) this);
        }
    }
}

在onNmeaMessage方法中接受数据

@Override
public void onNmeaMessage(String message, long timestamp) {
    Log.i("log2", "onNmeaMessage: "+ message);

}

接受到的数据 

onNmeaMessage: $GPDTM,,,,,,,,*4A
onNmeaMessage: $GPRMC,,V,,,,,,,,,,N,V*29
onNmeaMessage: $GPGNS,,,,,,N,,,,,,,V*79
onNmeaMessage: $GPGGA,,,,,,0,,,,,,,,*66
onNmeaMessage: $GBGSV,1,1,03,03,50,1,01,37,132,24,1*4F
onNmeaMessage: $GPGSA,A,1,,,,,,,,,,,,,,,,*32
onNmeaMessage: $GPVTG,,T,,M,,N,,K,N*2C
onNmeaMessage: $GPDTM,,,,,,,,*4A
onNmeaMessage: $GPRMC,,V,,,,,,,,,,N,V*29
onNmeaMessage: $GPGNS,,,,,,N,,,,,,,V*79
onNmeaMessage: $GPGGA,,,,,,0,,,,,,,,*66

有个小小的下次,申请权限的弹框不显示 , 需要通过设置打开位置权限,直接申请在小米手机上没有弹框提示信息

OnNmeaMessageListener 和 GpsStatus.Listener 不能同时继承 原理分析

不能同时继承的原因是在LocationManager类中的 convertKey 方法中

详细源码

public boolean addListener(@NonNull GpsStatus.Listener listener, @NonNull Executor executor)
        throws RemoteException {
    return addInternal(null, listener, executor);
}

public boolean addListener(@NonNull OnNmeaMessageListener listener,
        @NonNull Handler handler)
        throws RemoteException {
    return addInternal(null, listener, handler);
}

public boolean addListener(@NonNull OnNmeaMessageListener listener,
        @NonNull Executor executor)
        throws RemoteException {
    return addInternal(null, listener, executor);
}

@Override
protected GnssStatus.Callback convertKey(Object listener) {
    if (listener instanceof GnssStatus.Callback) {
        return (GnssStatus.Callback) listener;
    } else if (listener instanceof GpsStatus.Listener) {
        return new GnssStatus.Callback() {
            private final GpsStatus.Listener mGpsListener = (GpsStatus.Listener) listener;

            @Override
            public void onStarted() {
                mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED);
            }

            @Override
            public void onStopped() {
                mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STOPPED);
            }

            @Override
            public void onFirstFix(int ttffMillis) {
                mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_FIRST_FIX);
            }

            @Override
            public void onSatelliteStatusChanged(GnssStatus status) {
                mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
            }
        };
    } else if (listener instanceof OnNmeaMessageListener) {
        return new NmeaAdapter((OnNmeaMessageListener) listener);
    } else {
        throw new IllegalStateException();
    }
}

通过源码可知 如果 类继承了GpsStatus.Listener 直接走

if (listener instanceof GpsStatus.Listener) {
    return new GnssStatus.Callback() {
        private final GpsStatus.Listener mGpsListener = (GpsStatus.Listener) listener;

        @Override
        public void onStarted() {
            mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED);
        }

        @Override
        public void onStopped() {
            mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STOPPED);
        }

        @Override
        public void onFirstFix(int ttffMillis) {
            mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_FIRST_FIX);
        }

        @Override
        public void onSatelliteStatusChanged(GnssStatus status) {
            mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
        }
    };

就不会执行

if (listener instanceof OnNmeaMessageListener) {
    return new NmeaAdapter((OnNmeaMessageListener) listener);
} 

不会调用onNmeaReceived,不能通过onNmeaMessage返回nmea数据了

@Override
public void onNmeaReceived(long timestamp, String nmea) {
    execute((callback) -> {
        if (callback instanceof NmeaAdapter) {
            ((NmeaAdapter) callback).onNmeaMessage(nmea, timestamp);
        }
    });
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值