首先在 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); } }); }