Windows Mobile下GPS管理软件NavsGo之GPS侦测功能的开发.docx
- 文档编号:15588398
- 上传时间:2023-07-05
- 格式:DOCX
- 页数:14
- 大小:397.82KB
Windows Mobile下GPS管理软件NavsGo之GPS侦测功能的开发.docx
《Windows Mobile下GPS管理软件NavsGo之GPS侦测功能的开发.docx》由会员分享,可在线阅读,更多相关《Windows Mobile下GPS管理软件NavsGo之GPS侦测功能的开发.docx(14页珍藏版)》请在冰点文库上搜索。
WindowsMobile下GPS管理软件NavsGo之GPS侦测功能的开发
WindowsMobile下GPS管理软件NavsGo之GPS侦测功能的开发
关于
所谓GPS侦测功能就是扫描手机上所有可用的GPS设备(availableGPSdevices),把各个设备运行状态展现给用户,如果发现问题,通过友善的方式提示用户如果解决设备连通性问题。
这些建议包括启动GPS设备,修改GPSIntermediateDriver的配置,启动蓝牙GPS设备等等。
实现
这个模块是GPS.net作者jperson的一个demo程序,原程序可以到 GPSDiagnosticsfor.NET 下载。
我做了少量修改加到NavsGo里面来了。
发现/检测功能(Detection)
发现功能在上篇文章讲过,通过注册静态事件,然后回调相应的处理函数。
/*HookintoGPSdevicedetectionevents.Theseeventsarestatic,allowingthemto
*beeasilysunkbyanyotherclassorform.
*/
Devices.DeviceDetectionStarted+=newEventHandler(Devices_DeviceDetectionStarted);
Devices.DeviceDetectionCompleted+=newEventHandler(Devices_DeviceDetectionCompleted);
Devices.DeviceDetected+=newEventHandler
Devices.DeviceDetectionAttempted+=newEventHandler
Devices.DeviceDetectionAttemptFailed+=newEventHandler
由于GPS.net是开源的,我们这次钻到他的源代码看看Detection的实现逻辑。
启动发现功能是在Devices.BeginDetection()函数里面。
publicstaticvoidBeginDetection()
{
//Startdetectiononanotherthread.
if(_IsDetectionInProgress)
return;
//Signalthatdetectionisinprogress
_IsDetectionInProgress=true;
//Startathreadformanagingdetection
_DetectionThread=newThread(newThreadStart(DetectionThreadProc));
_DetectionThread.Name="GPS.NETDeviceDetector()";
_DetectionThread.IsBackground=true;
#if!
PocketPC
//Dodetectioninthebackground
_DetectionThread.Priority=ThreadPriority.Lowest;
#endif
_DetectionThread.Start();
#ifPocketPC
//Signalthatthethreadisalive(noThread.IsAliveontheCF:
P)
_IsDetectionThreadAlive=true;
#endif
}
启动发现过程,系统会启动一个线程调用DetectionThreadProc()进行发现。
下面是DetectionThreadProc()函数。
privatestaticvoidDetectionThreadProc()
{
try
{
//Signalthatitstarted
OnDeviceDetectionStarted();
//Monitorthisthreaduptothetimeout,thenquit
ThreadPool.QueueUserWorkItem(newWaitCallback(DetectionThreadProcWatcher));
#ifPocketPC
//AreweusingtheGPSIntermediateDriver?
GpsIntermediateDrivergpsid=GpsIntermediateDriver.Current;
//IstheGPSIDsupported?
if(gpsid!
=null)
{
//Yes.Testittobesure
gpsid.BeginDetection();
//Waitforonedevicetogetdetected.Wasitconfirmed?
if(gpsid.WaitForDetection())
{
//Yes.Ifweonlyneedonedevice,exit
if(_IsOnlyFirstDeviceDetected)
return;
}
}
#endif
/*Ifwegethere,theGPSIntermediateDriverisnotresponding!
*/
intcount;
#regionDetectBluetoothdevices
//IsBluetoothsupportedandturnedon?
if(IsBluetoothSupported&&IsBluetoothEnabled)
{
//Startbluetoothdetectionforeachdevice
count=_BluetoothDevices.Count;
for(intindex=0;index _BluetoothDevices[index].BeginDetection(); } #endregion #regionDetectserialGPSdevices if(AllowSerialConnections) { count=SerialDevices.Count; for(intindex=0;index _SerialDevices[index].BeginDetection(); /*Ifwe'reperforming"exhaustive"detection,portsarescanned *evenifthere'snoevidencetheyactuallyexist.Thiscanhappeninrare *cases,suchaswhenaPCMCIAGPSdeviceispluggedinandfailstocreate *aregistryentry. */ if(_AllowExhaustiveSerialPortScanning) { //TryallportsfromCOM0: uptothemaximumportnumber for(intindex=0;index<_MaximumSerialPortNumber;index++) { //Isthisportalreadybeingchecked? boolalreadyBeingScanned=false; for(intexistingIndex=0;existingIndex<_SerialDevices.Count;existingIndex++) { if(_SerialDevices[existingIndex].PortNumber.Equals(index)) { //Yes.Don'ttestitagain alreadyBeingScanned=true; break; } //Ifit'salreadybeingscanned,stop if(alreadyBeingScanned) break; } //Ifit'salreadybeingscanned,skiptothenextport if(alreadyBeingScanned) continue; //Thisisanewdevice.Scanit SerialDeviceexhaustivePort=newSerialDevice("COM"+index.ToString()+": "); exhaustivePort.BeginDetection(); } } } #endregion #regionDiscovernewBluetoothdevices //IsBluetoothsupportedandturnedon? if(IsBluetoothSupported&&IsBluetoothEnabled) { /*NOTE: Formobiledevices,onlyoneconnectionisallowedatatime. *Asaresult,weuseastaticSyncRoottoensurethatconnections *anddiscoveryhappensinserial.Forthisreason,wewillnotattempt *todiscoverdevicesuntil*after*tryingtodetectexistingones. */ #ifPocketPC //Waitforexistingdevicestobetested count=_BluetoothDevices.Count; for(intindex=0;index { //Completedetectionforthisdevice _BluetoothDevices[index].WaitForDetection(); } #endif //Beginsearchingforbrandnewdevices BluetoothDevice.DiscoverDevices(true); //Blockuntilthatsearchcompletes BluetoothDevice.DeviceDiscoveryThread.Join(); } #endregion #regionWaitforalldevicestofinishdetection /*Alistholdsthewaithandlesofdevicesbeingdetected.Whenitisempty, *detectionhasfinishedonallthreads. */ while(_CurrentlyDetectingWaitHandles.Count! =0) { try { ManualResetEventhandle=_CurrentlyDetectingWaitHandles[0]; #if! PocketPC if(! handle.SafeWaitHandle.IsClosed) #endif handle.WaitOne(); } catch(ObjectDisposedException) { /*Insomerarecasesadevicewillgetdisposedofandnulledout. *So,regardlessofwhathappenswecanremovetheitem. */ } finally { _CurrentlyDetectingWaitHandles.RemoveAt(0); } } #endregion #ifPocketPC #regionReconfiguretheGPSIntermediateDriver(ifnecessary) /*TheGPSIntermediateDrivermaynothavetheright"ProgramPort"(actualGPSport/baudrate) *settings.Nowthatdetectionhascompleted,let'sseeiftheGPSIDneedsconfiguration. *IfitisflaggedasNOTbeingaGPSdevice,thenitcouldnotconnect.Inthiscase,let's *findthemostreliableserialdeviceanduseit. */ if( //IstheGPSIDsupported? gpsid! =null //Areweallowedtoconfigureit? &&gpsid.IsAutomaticallyConfigured //IsitcurrentlyNOTidentifiedasaGPSdevice? (connectionsfailed) &&! gpsid.IsGpsDevice) { //LookthrougheachconfirmedGPSdevice count=_GpsDevices.Count; for(intindex=0;index { //Isitaserialdevice? SerialDevicedevice=_GpsDevices[index]asSerialDevice; if(device==null) continue; //Yes.Useit! try { gpsid.HardwarePort=device; //TheGPSIDisnowworking Add(gpsid); } catch(Exceptionex) { //Notifyoftheerrorgracefully OnDeviceDetectionAttemptFailed(newDeviceDetectionException(gpsid,ex)); } //That'sthebestdevice,soquit break; } } #endregion #endif //Signalcompletion OnDeviceDetectionCompleted(); } catch(ThreadAbortException) { #regionAbortdetectionforalldevices #ifPocketPC //StopdetectionfortheGPSID if(GpsIntermediateDriver.Current! =null) GpsIntermediateDriver.Current.CancelDetection(); #endif //StopdetectionforeachBluetoothdevice for(intindex=0;index<_BluetoothDevices.Count;index++) _BluetoothDevices[index].CancelDetection(); //Stopdetectionforeachserialdevice for(intindex=0;index<_SerialDevices.Count;index++) _SerialDevices[index].CancelDetection(); #endregion //Waitforallthethreadstodie.Just...sitandwatch.Andwait. while(_CurrentlyDetectingWaitHandles.Count! =0) { try{_CurrentlyDetectingWaitHandles[0].WaitOne();} catch{} finally{_CurrentlyDetectingWaitHandles.RemoveAt(0);} } //Signalthecancellation if(DeviceDetectionCanceled! =null) DeviceDetectionCanceled(null,EventArgs.Empty); } finally { //Detectionisnolongerinprogress _DetectionCompleteWaitHandle.Set(); _CurrentlyDetectingWaitHandles.Clear();//<--Alreadyempty? _IsDetectionInProgress=false; #ifPocketPC //Signalthatthethreadisalive(noThread.IsAliveontheCF: P) _IsDetectionThreadAlive=false; #endif } } DetectionThreadProc()负责整个发现过程,是一个很长的函数,有必要重构一下,把它分离(split)成几个小函数。 他的处理逻辑是,检测超时,一旦发现发现过程超时,就好中途停止所有的处理。 然后按顺序检测设备。 检测的设备包括GPSIntermediateDriver设备(GpsIntermediateDriver),串口设备(SerialDevice)和蓝牙设备(BluetoothDevice)。 支持的设备类图如下: 所有设备都是继承于父类Device,这样可以通过容器类Devices类统一管理所有设备的对象,通过多态的方式去调用各个具体设备的处理函数来实现发现过程。 对于每个独立的设备,他们统一发现流程是启动一个线程,然后试图打开该设备,如果超时,认为设备不可用,如果在超时之前读取到数据就分析输出数据,如果数据是标准的NMEA就认为这个是GPS设备。 NMEA相关的可以参考.NETCompactFramework下的GPSNMEAdata数据分析。 GPSIntermediateDriver设备的发现 发现过程首先检查的是GPSIntermediateDriver设备。 在WindowsMobile5+和Wince6+的系统下一般都内嵌GPSIntermediateDriver,关于GPSIntermediateDriver的开发可以参考30Daysof.NET[WindowsMobileApplications]-Day03: GPSCompass(GPS指南针) 。 我计划增加GPSIntermediateDriver管理功能到NavsGo里面,后续会把GPSIntermediateDriver管理的开发写下来。 已经配对了的蓝牙设备的发现 检测完GPSIntermediateDriver设备,就开始检查已经配对了的蓝牙设备(PairedBluetoothDevices),这些已经配对了的蓝牙设备保存在注册表HKEY_LOCAL_MACHINE\SOFTWARE\GeoFrameworks\GPS.NET\3.0\Devices\Bluetooth\中。 关于蓝牙配对也可以参考一下 .NETCompactFramework下的Bluetooth设备的配对。 软件意义上的串口设备的发现 检测完已经配对了的蓝牙设备后,就开始检查串口设备,这里的串口设备是指软件意义上的串口,不是仅仅只通过硬件串口线连接的设备。 由于 NMEA0183 的规范规定GPS设备的联通性通过波特率(Baudrate)为4800的串口设备。 所以GPS设备厂商尽管使用其他联通方式,但是都可以转成软件上的串口设备。 例如USBGPS设备可以通过驱动转成串口设备,蓝牙可以建立虚拟串口,关于虚拟串口可以参考 .NETCompactFramework下的Bluetooth开发之BluetoothVirtualSerialPort。 总的来说,这里软件意义上的串口,真实的设备可能是真正的串口线,USB,PCMCIA,蓝牙,红外等。 新蓝牙设备的发现 做完GPSIntermediateDriver设备,已经配对了的蓝牙设备和软件意义上的串口的发现流程后,进入了对新蓝牙设备的发现过程,这些蓝牙设备是不在已经配对了的蓝牙设备的范畴里面的,是手机周边新的蓝牙设备。 由于手机对蓝牙的通信只能是一对一,也就是一个时间内一台手机只能和一个蓝牙设备进行通信,所以在发现新蓝牙设备之前,需要先等待已经配对了的蓝牙设备的发现过程的结束。 关于蓝牙设备的开发和发现可以参考一下 .NETCompactFramework下的Bluetooth开发之WindowsEmbeddedSourceToolsforBlueto
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Windows Mobile下GPS管理软件NavsGo之GPS侦测功能的开发 Mobile GPS 管理软件 NavsGo 侦测 功能 开发