3

嗨,Garmin 开发人员,

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

按照开发者网站上的详细信息,我已经设法让它工作,但是有很多丢失的消息没有被发送,并且手表接收的值比发送的值少。

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

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

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

示例应用程序.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 模块可能不支持该速率的通信?

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

4

2 回答 2

1

认为Connect 消息传递系统只是进入一些损坏状态,然后没有消息会通过。您可以尝试在 onStart 方法中设置邮箱侦听器而不是初始化。

还有一种新方法可以使消息阅读更容易。它仍然基本上没有记录,但我听说它将在下一个 SDK 版本中记录。然而,它已经在每一个 ConnectIQ 手表上运行。方法是:

Comm.registerForPhoneAppMessages(method(:onMsg));

在你的回调方法中你做什么:

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

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

于 2017-01-27T12:24:05.393 回答
0

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

我希望实现的是以下生活:

假设来自 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
    }
}
于 2017-02-10T21:53:08.473 回答