zoukankan      html  css  js  c++  java
  • How to Use a Bluetooth GPS(转载自nokia论坛)

    How to Use a Bluetooth GPS

    The GPS class shows how to use a Bluetooth GPS device and read location information from it. It displays a selection dialog for the user and starts receiving data from the selected device. Currently it only parses the RMC message which is required in all GPS devices. This gives the latitude, longitude, heading and speed information but not altitude nor dilution.

    You need to implement messaging for lost signal etc if you want to show them to the user.

    You can also use the Parse() method to convert the received values to degrees, minutes and seconds as well as a combined integer value multiplied by 65536.

    This example assumes that the GPS device uses RFCOMM channel 1 as data channel. This has been the case in every device I've used, so it's a safe assumption.

     

    GPS.h

    #ifndef GPS_H_

    #define GPS_H_

     

    #include <e32std.h>

    #include <btmanclient.h>

    #include <btextnotifiers.h>

    #include <es_sock.h>

    #include <in_sock.h>

    #include <bt_sock.h>

     

    class GPS : public CActive

    {

    public:

        GPS();

        virtual ~GPS();

        void ConstructL();

     

        void DoCancel();

        void RunL();

     

        TPtrC Lat();

        TPtrC Lon();

     

        TInt            speed, heading;

     

    private:

        TBool Active;

        TBuf8<32> lat, lon;

     

        TBuf8<256> line;

        TBuf8<32> data;

        int state;

        RSocket iSendingSocket;

        RSocketServ iSocketServer;

    };

     

    #endif /*GPS_H_*/

     

    GPS.cpp

    #include "GPS.h"

    #include <e32math.h>

     

    _LIT8(ZERO, "0");

    _LIT(RFCOMM, "RFCOMM");

    _LIT8(KGPS, "GPS");

     

    void Parse(TDesC8 &data, TInt °, TInt &min, TInt &sec, TInt32 &whole)

    {

        TLex8 lex(data);

     

        lex.Val(deg);

        lex.Inc();

        lex.Val(min);

        sec = min * 60;

        int l = (data.Length() - data.Find(_L8(".")));

        int x = 1;

        while (l-- > 0)

            x *= 10;

        sec /= x/100;

     

        min = deg % 100;

        deg /= 100;

     

        whole = deg * 65536 + (min * 65536 / 60) + (sec * 65536 / 36000);

    }

     

    GPS::GPS() : CActive(EPriorityLow)

    {

        state = 0;

    }

     

    GPS::~GPS()

    {

        TRAPD(err, Cancel());

        TRAP(err, Deque());

    }

     

    void GPS::RunL()

    {

        int i, j;

     

        if (iStatus == KErrNone)

      {

            if (state == 1)

            {

                state = 2;

                line.Zero();

                iSendingSocket.Read(data, iStatus);

                SetActive();

            }

            else if (state == 2)

            {

                int rpos = 0;

     

                while ((rpos = data.Locate('\r')) != KErrNotFound)

                {

                    line.Append(data.Left(rpos));

                    if (data.Length() > rpos + 2)

                    {

                        if (data[rpos + 1] == '\n')

                            data.Copy(data.Mid(rpos+2));

                        else

                            data.Copy(data.Mid(rpos+1));

                    }

                    else

                    {

                        data.Zero();

                    }

     

                    if (line.Length() > 10)

                    {

                        // RMC - lat, lon, speed

                        if ((line[3] == 'R') && (line[4] == 'M') && (line[5] == 'C'))

                        {

                            j = i = 0;

                            while ((i < line.Length()) && (line[i] != ','))

                                i++;

                            i++;

     

                            j = i;

                            while ((i < line.Length()) && (line[i] != ','))

                                i++;

                            i++;

     

                            // If there is no signal, this is not A

                            if (line[i] != 'A')

                            {

                                lat.Copy(ZERO);

                                lon.Copy(ZERO);

                                latdeg = londeg = latmin = lonmin = latsec = lonsec = 0;

                                line.Zero();

                                iSendingSocket.Read(data, iStatus);

                                SetActive();

                                return;

                            }

     

                            while ((i < line.Length()) && (line[i] != ','))

                                i++;

                            i++;

                            j = i;

                            while ((i < line.Length()) && (line[i] != ','))

                                i++;

     

                            // Copy latitude from the message

                            lat.Copy(line.Mid(j, i-j));

                            // If it's southern hemisphere, negate the value

                            if (line[i+1] == 'S')

                                lat.Insert(0, _L8("-"));

     

                            i += 3;

                            j = i;

                            while ((i < line.Length()) && (line[i] != ','))

                                i++;

     

                            // Copy longitude from the message

                            lon.Copy(line.Mid(j, i-j));

                            // If it's western hemisphere, negate the value

                            if (line[i+1] == 'W')

                                lon.Insert(0, _L8("-"));

     

                            i += 3;

                            j = i;

                            while ((i < line.Length()) && (line[i] != ','))

                                i++;

     

                            // Read speed from the message

                            TLex8 lex(line.Mid(j, i-j));

                            lex.Val(speed);

                            speed *= 10;

                            if (lex.Peek() == '.')

                            {

                                lex.Inc();

                                if (lex.Peek() != 0)

                                    speed += ((int)lex.Peek() - '0');

                            }

                            // Convert speed from knots to km/h

                            speed *= 1852;

                            speed /= 1000;

     

                            i++;

                            j = i;

                            while ((i < line.Length()) && (line[i] != ','))

                                i++;

     

                            // Read heading from the message

                            lex.Assign(line.Mid(j, i-j));

                            lex.Val(heading);

                            heading *= 10;

                            // Check if it's not integer

                            if (lex.Peek() == '.')

                            {

                                lex.Inc();

                                if (lex.Peek() != 0)

                                    heading += ((int)lex.Peek() - '0');

                            }

                        }

                    }

     

                    line.Zero();

                }

     

                line.Append(data);

     

                iSendingSocket.Read(data, iStatus);

                SetActive();

            }

      }

        // Error occurred...

        else

        {

            lat.Copy(ZERO);

            lon.Copy(ZERO);

        }

    }

     

    void GPS::DoCancel()

    {

        if (state > 0)

            iSendingSocket.Close();

        iSocketServer.Close();

    }

     

    void GPS::ConstructL()

    {

        TBTDeviceResponseParamsPckg resultPckg;

     

        CActiveScheduler::Add(this);

     

        // 1. Create a notifier

        RNotifier notif;

        User::LeaveIfError(notif.Connect());

     

        if (gpsid.Length() == 0)

        {

            state = 0;

            // 2. Start the device selection plug-in

            TBTDeviceSelectionParams selectionFilter;

            TUUID targetServiceClass(0x2345);

            selectionFilter.SetUUID(targetServiceClass);

            TBTDeviceSelectionParamsPckg pckg(selectionFilter);

            TRequestStatus status;

            notif.StartNotifierAndGetResponse(status,

    KDeviceSelectionNotifierUid, pckg, resultPckg);

            User::After(2000000);

     

            // 3. Extract device name if it was returned

            User::WaitForRequest(status);

     

            User::LeaveIfError(iSocketServer.Connect());

     

            if (status.Int() == KErrNone)

            {

                User::LeaveIfError(iSendingSocket.Open(iSocketServer,

    RFCOMM));

                TBTSockAddr address;

                gpsid.Copy(resultPckg().BDAddr().Des());

                address.SetBTAddr(resultPckg().BDAddr());

                // GPS devices usually use port 1 as data channel

                // so we don't have to query it

                address.SetPort(1);

     

                state = 1;

                iSendingSocket.Connect(address, iStatus);

                SetActive();

            }

            else

            {

                CHainMAppView::Static()->Notification(EGPSNotFound);

            }

        }

        else

        {

            User::LeaveIfError(iSocketServer.Connect());

            User::LeaveIfError(iSendingSocket.Open(iSocketServer, RFCOMM));

     

            TBTSockAddr address;

            TBTDevAddr a(gpsid);

            address.SetBTAddr(a);

            address.SetPort(1);

     

            state = 1;

            iSendingSocket.Connect(address, iStatus);

            SetActive();

        }

    }

     

    TPtrC GPS::Lat()

    {

        return lat;

    }

     

    TPtrC GPS::Lon()

    {

        return lon;

    }

  • 相关阅读:
    【Android Developers Training】 73. 布局变化的动画
    【Android Developers Training】 72. 缩放一个视图
    【Android Developers Training】 71. 显示翻牌动画
    svn更改地址怎么办
    python学习手册
    failed to bind pixmap to texture
    Ubuntu 12.04安装Google Chrome
    svn update 时总是提示 Password for '默认密钥' GNOME keyring: 输入密码
    重设SVN 的GNOME keyring [(null)] 的密码
    Nginx + uWSGI + web.py 搭建示例
  • 原文地址:https://www.cnblogs.com/qqivoryqq/p/1625169.html
Copyright © 2011-2022 走看看