GPS北斗双模技术应用开发研究—应用数据交互
Android开发原则就是谁对哪个数据感兴趣就可以通过listener去监听一下,那边定位数据肯定也是这样的,关于位置上报的话,笔者不准备在这累赘了,网上好多文章,下面就讲一下双模相关的北斗gps卫星星图搜星具体情况的数据上报以及私有协议的定制。
在locationmanager里面有一个接口addGpsStatusListener,在应用里通过这个接口把listen传下去,这中间有很多过程,最终这个listener在location的provider里面存了起来,中间被service转了一手,但是service里面是直接用的provider的addGpsStatusListener。下面可以看看service里面的addGpsStatusListener接口情况,如下:
public boolean addGpsStatusListener(IGpsStatusListener listener, String packageName) { if (mGpsStatusProvider == null) { return false; } int allowedResolutionLevel = getCallerAllowedResolutionLevel(); checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, LocationManager.GPS_PROVIDER); final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { if (!checkLocationAccess(uid, packageName, allowedResolutionLevel)) { return false; } } finally { Binder.restoreCallingIdentity(ident); } try { mGpsStatusProvider.addGpsStatusListener(listener); } catch (RemoteException e) { Slog.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e); return false; } return true; }
这里就注册下去了。这样就相当于在provider里面就挂了个钩子了,一旦有新数据更新就可以直接传到应用里面了,当然这个listener中间转的那几手有兴趣的可以去看看代码,都不难看懂的。那看看卫星sv状态上报吧,直接触发了listener的onSvStatusChanged接口,如下:
private void reportSvStatus() { int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); synchronized (mListeners) { int size = mListeners.size(); for (int i = 0; i < size; i++) { Listener listener = mListeners.get(i); try { listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK], mSvMasks[BD_SVS_NUM], mSvMasks[BD_EPHEMERIS_MASK], mSvMasks[BD_ALMANAC_MASK],mSvMasks[BD_USED_FOR_FIX_MASK]); } catch (RemoteException e) { Log.w(TAG, "RemoteException in reportSvInfo"); mListeners.remove(listener); // adjust for size of list changing size--; } } }
这样就call到了GpsStatusListenerTransport里面的onSvStatusChanged了,在这里面要下点文章,它会发送一个GpsStatus.GPS_EVENT_SATELLITE_STATUS的消息,但是没有带参数,笔者就把两个参数利用起来了,一个存gps的数量,一个存北斗的数量。这个消息发送出去以后,会在他的handle里面处理转换一次。
private final Handler mGpsHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == NMEA_RECEIVED) { synchronized (mNmeaBuffer) { int length = mNmeaBuffer.size(); for (int i = 0; i < length; i++) { Nmea nmea = mNmeaBuffer.get(i); mNmeaListener.onNmeaReceived(nmea.mTimestamp, nmea.mNmea); } mNmeaBuffer.clear(); } } else { // synchronize on mGpsStatus to ensure the data is copied atomically. synchronized(mGpsStatus) { if(GpsStatus.GPS_EVENT_SATELLITE_STATUS == msg.what){ int pri_event ; pri_event = 0x77 + (msg.arg1<<8) + (msg.arg2<<16); //Log.d(TAG, "LM: msg.arg1 "+msg.arg1 +" msg.arg2 "+msg.arg2+ " pri "+pri_event); mListener.onGpsStatusChanged(pri_event); } mListener.onGpsStatusChanged(msg.what); } } }
因此,在转发消息的时候做一下特殊处理,合成一个特殊的消息,带上我们的gps数量北斗数量,其他没有什么特别的了,第三方应用同样也可以收到sv的变化,只是不知道gps跟北斗具体的数量。其他没有差异。