Android和Garmin FR230之间的BLE直接消息传递通信故障(SDK 1.3.x)

时间:2016-12-23 19:25:42

标签: java android bluetooth garmin connectiq

嗨,Garmin开发人员,

我一直在尝试在我的Android应用程序和我的connectIQ应用程序之间(在Garmin Forerunner 230,SDK版本1.3.x上)开发BLE上的直接消息传递通信设置。这里的目标是Android应用程序正在收集一些数据,然后将其推送到监视应用程序。

关于developer site的详细信息,我设法让这个工作正常,但是有很多丢弃的消息无法发送,并且手表获得的值少于发送。

在Android上,我在调试语句中得到此状态(ConnectIQ.IQMessageStatus)= FAILURE_DURING_TRANSFER。 ' 240'是发送的数据。

  

D / GarminMessenger:onMessageStatus:消息:240,设备:Forerunner 230,FAILURE_DURING_TRANSFER

这是我在garmin上的应用代码:

SampleApp.mc

using Toybox.Application as App;
using Toybox.Communications as Comm;
using Toybox.WatchUi as Ui;
using Toybox.System as Sys;

var mailMethod;
var crashOnMessage = false;

var msg;

class SampleApp extends App.AppBase {

    function initialize() {
        AppBase.initialize();
        Sys.println("app-initialize()");

        msg = "0";

        mailMethod = method(:onMail);
        Comm.setMailboxListener(mailMethod);
        Sys.println("app-initialize(): mail box listener has been set");
    }

    // onStart() is called on application start up
    function onStart(state) {
        System.println("app-onStart()");
    }

    // Return the initial view of your application here
    function getInitialView() {
        Sys.println("app-getInitialView()");
        return [ new SampleAppView() ];
    }

    function onMail(mailIter) {
        var mail = mailIter.next();

        while(mail!=null) {
            Sys.println("app-onMail: received - "+mail);

            message = mail.toString();
            Ui.requestUpdate();
            mail = mailIter.next();
        }

        Comm.emptyMailbox();
    }

    // onStop() is called when your application is exiting
    function onStop(state) {
        System.println("app-onStop()");
    }   
}

class CommListener extends Comm.ConnectionListener {
    function initialize() {
        Comm.ConnectionListener.initialize();
        sys.println("commlistener-initialize");
    }

    function onComplete() {
        Sys.println("commlistener-onComplete: Transmit Complete");
    }

    function onError() {
        Sys.println("commlistener-onError: Transmit Failed");
    }
}

关于可能导致此问题的任何想法?我正在Android端执行所有必要的检查以验证Garmin手表是否已配对并已连接(并且应用程序已打开)。

这可能发生的一个原因是我试图每秒发送1-2个数据值(每个都有一个ConnectIQ.sendMessage()),所以Garmin设备/ BLE模块可能不支持该速率的通信?

提前感谢您提供解决方案和建议。

2 个答案:

答案 0 :(得分:1)

认为 Connect消息系统刚进入某个破坏状态,然后没有消息通过。 您可以尝试在onStart方法中设置邮箱侦听器而不是初始化。

还有一种新方法可以使信息阅读更容易。它仍然很大程度上没有记录,但我得到了一个词,它将在下一个SDK版本中记录。但是,它已经在每个ConnectIQ手表上工作。 方法是:

Comm.registerForPhoneAppMessages(method(:onMsg));

你在回调方法中的位置:

function onMsg(msg) {
    handleIncomingMessage(msg.data.toString());
}

或类似的东西。输入对象msg属于类 Toybox::Communications::Message 可能(这还没有记录)。

答案 1 :(得分:0)

所以我在Garmin开发者论坛here上发布了类似的问题,并得到了我的问题的部分答案。从那里发布摘要。

我希望实施的是以下内容:

假设来自Android的消息是1,2,3,4,5:我想要的 应用程序在收到消息时更新UI,实时如下:

app-onMail: received - 1
//update the UI
app-onMail: received - 2
//update the UI
app-onMail: received - 3
//update the UI
app-onMail: received - 4
//update the UI
app-onMail: received - 5
//update the UI

相反,这种情况发生了

app-onMail: received - 1 
app-onMail: received - 2 
app-onMail: received - 3 
app-onMail: received - 4 
app-onMail: received - 5 
//update the UI 
//update the UI 
//update the UI 
//update the UI 
//update the UI

答案

  

框架轮询以查看是否有新的未读邮件。如果有,则调用应用程序onMail()回调,该回调消耗队列中的每条消息,并重复设置一个标志,指示UI需要更新。调用返回后,框架会检查标志以查看是否需要更新UI,如果是,则调用onUpdate()作为活动视图。

因此,如果我以5秒的间隔从Android发送消息,我只能显示每条消息。由于其消息轮询频率,我无法找到以更高速率接收和显示数据的方法。

我的回复者建议维护一个邮件项目队列(或只是一个计数器),然后在抽奖之间处理邮件项目,如下所示:

class MyApp extends App.AppBase
{
    hidden var _M_messages;
    hidden var _M_count;

    function initialize() {
        AppBase.initialize();
        _M_messages = new [10];
        _M_count = 0;
    }

    function getInitialView() {
        return [ new MyView() ];
    }

    function onStart(params) {
        Comm.setMailboxListener(self.method(:onMail));
    }

    function onStop(params) {
        Comm.setMailboxListener(null);
    }

    function onMail(mailIter) {

        var mail = mailIter.next();
        while (mail != null) {

            // only track up to 10 messages
            if (_M_count < 10) {
                _M_messages[_M_count] = mail;
                ++_M_count;
            }
            else {
                break;
            }

            mail = mailIter.next();
        }

        Comm.emptyMailbox();

        startProcessingMessages();
    }


    hidden function startProcessingMessages() {
        if (_M_timer == null) {
            _M_timer = new Timer.Timer();
            _M_timer.start(self.method(:processOneMessage), 250, true);
        }
    }

    hidden function stopProcessingMessages() {
        if (_M_timer != null) {
            _M_timer.stop();
            _M_timer = null;
        } 
    }

    function getMessageCount() {
        return _M_messages;
    }

    function processOneMessage() {
        if (_M_count != 0) {
            --_M_count;
            var mail = _M_messages[_M_count];
            _M_messages[_M_count] = null;

            // process the message here

           Ui.requestUpdate();

           if (_M_count == 0) {
               stopProcessingMessages();
           }
        }
    }
}

class MyView extends Ui.View
{
    hidden var _M_app;

    function initialize(app) {
        View.initialize();
        _M_app = app;
    }

    function onUpdate(dc) {

        var mailMessages = _M_app.getMessageCount();

        // draw the number of mail messages
    }
}